iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++OpenCV实战之图像透视矫正
  • 392
分享到

C++OpenCV实战之图像透视矫正

2024-04-02 19:04:59 392人浏览 薄情痞子
摘要

目录前言一、图像预处理二、轮廓提取1.提取最外轮廓2.提取矩形四个角点3.将矩形角点排序三、透视矫正四、源码前言 本文将使用OpenCV c++ 进行图像透视矫正。 一、图像预处理

前言

本文将使用OpenCV c++ 进行图像透视矫正。

一、图像预处理

原图如图所示。首先进行图像预处理。将图像进行灰度、滤波、二值化、形态学等操作,目的是为了下面的轮廓提取。在这里我还使用了形态学开、闭操作,目的是使整个二值图像连在一起。大家在做图像预处理时,可以根据图像特征自行处理。

	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	Mat gaussian;
	GaussianBlur(gray, gaussian, Size(3, 3), 0);

	Mat thresh;
	threshold(gaussian, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
	Mat open;
	morphologyEx(thresh, open, MORPH_OPEN, kernel);

	Mat kernel1 = getStructuringElement(MORPH_RECT, Size(7, 7));
	Mat close;
	morphologyEx(open, close, MORPH_CLOSE, kernel1);

如图就是经过图像预处理得到的二值图像。

二、轮廓提取

1.提取最外轮廓

	vector<vector<Point>>contours;	
	findContours(close, contours, RETR_EXTERNAL, CHaiN_APPROX_SIMPLE);

使用findContours、RETR_EXTERNAL就可以提取出物体最外轮廓。

2.提取矩形四个角点

接下来将使用approxPolyDP进行多边形轮廓拟合,目的是为了找到矩形的四个角点。关于approxPolyDP api大家可以自行百度查看其用法。

	vector<vector<Point>>conPoly(contours.size());
	vector<Point>srcPts;

	for (int i = 0; i < contours.size(); i++)
	{
		double area = contourArea(contours[i]);

		if (area > 10000)
		{
			double peri = arcLength(contours[i], true);

			approxPolyDP(contours[i], conPoly[i], 0.02*peri, true);
             //获取矩形四个角点
			srcPts = { conPoly[i][0],conPoly[i][1],conPoly[i][2],conPoly[i][3] };

		}

	}

3.将矩形角点排序

由于我们之前使用的approxPolyDP获取的角点是无序的,所以我们得确定各角点所在的位置。在这里我使用的算法是根据其角点所在图像位置特征确定左上、左下、右下、右上四个点。

	int width = src.cols / 2;
	int height = src.rows / 2;
	int T_L, T_R, B_R, B_L;

	for (int i = 0; i < srcPts.size(); i++)
	{
		if (srcPts[i].x < width && srcPts[i].y < height)
		{
			T_L = i;
		}
		if (srcPts[i].x > width && srcPts[i].y < height)
		{
			T_R = i;
		}
		if (srcPts[i].x > width && srcPts[i].y > height)
		{
			B_R = i;
		}
		if (srcPts[i].x < width && srcPts[i].y > height)
		{
			B_L = i;
		}
		
	}

如图所示。至此已经完成了矩形四个角点的定位。接下来就可以使用透视变换进行图像矫正了。

三、透视矫正

在这里我们需要知道透视变换一个原理:

变换后,图像的长和宽应该变为:

长 = max(变换前左边长,变换前右边长)

宽 = max(变换前上边长,变换前下边长)

设变换后图像的左上角位置为原点位置。

	double LeftHeight = EuDis(srcPts[T_L], srcPts[B_L])	
	double RightHeight = EuDis(srcPts[T_R], srcPts[B_R]);
	double MaxHeight = max(LeftHeight, RightHeight);

	double UpWidth = EuDis(srcPts[T_L], srcPts[T_R]);
	double DownWidth = EuDis(srcPts[B_L], srcPts[B_R]);
	double MaxWidth = max(UpWidth, DownWidth);

确定变换后的长宽之后,就可以使用getPerspectiveTransfORM、warpPerspective进行透视矫正了。

//这里使用的顺序是左上、右上、右下、左下顺时针顺序。SrcAffinePts、DstAffinePts要一一对应
	Point2f SrcAffinePts[4] = { Point2f(srcPts[T_L]),Point2f(srcPts[T_R]) ,Point2f(srcPts[B_R]) ,Point2f(srcPts[B_L]) };
	Point2f DstAffinePts[4] = { Point2f(0,0),Point2f(MaxWidth,0),Point2f(MaxWidth,MaxHeight),Point2f(0,MaxHeight) };

	Mat M = getPerspectiveTransform(SrcAffinePts, DstAffinePts);
	
	Mat DstImg;
	warpPerspective(src, DstImg, M, Point(MaxWidth, MaxHeight));

这就是进行透视矫正之后的效果。

四、源码

#include<iOStream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

double EuDis(Point pt1, Point pt2)
{
	return sqrt((pt2.x - pt1.x)*(pt2.x - pt1.x) + (pt2.y - pt1.y)*(pt2.y - pt1.y));
}

int main()
{

	Mat src = imread("1.jpg");
	if (src.empty())
	{
		cout << "No Image!" << endl;
		system("pause");
		return -1;
	}

	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	Mat gaussian;
	GaussianBlur(gray, gaussian, Size(3, 3), 0);

	Mat thresh;
	threshold(gaussian, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
	Mat open;
	morphologyEx(thresh, open, MORPH_OPEN, kernel);

	Mat kernel1 = getStructuringElement(MORPH_RECT, Size(7, 7));
	Mat close;
	morphologyEx(open, close, MORPH_CLOSE, kernel1);

	vector<vector<Point>>contours;	
	findContours(close, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

	vector<vector<Point>>conPoly(contours.size());
	vector<Point>srcPts;

	for (int i = 0; i < contours.size(); i++)
	{
		double area = contourArea(contours[i]);

		if (area > 10000)
		{
			double peri = arcLength(contours[i], true);

			approxPolyDP(contours[i], conPoly[i], 0.02*peri, true);

			srcPts = { conPoly[i][0],conPoly[i][1],conPoly[i][2],conPoly[i][3] };

		}

	}

	int width = src.cols / 2;
	int height = src.rows / 2;
	int T_L, T_R, B_R, B_L;

	for (int i = 0; i < srcPts.size(); i++)
	{
		if (srcPts[i].x < width && srcPts[i].y < height)
		{
			T_L = i;
		}
		if (srcPts[i].x > width && srcPts[i].y < height)
		{
			T_R = i;
		}
		if (srcPts[i].x > width && srcPts[i].y > height)
		{
			B_R = i;
		}
		if (srcPts[i].x < width && srcPts[i].y > height)
		{
			B_L = i;
		}
		
	}

	//circle(src, srcPts[T_L], 10, Scalar(0, 0, 255), -1);
	//circle(src, srcPts[T_R], 10, Scalar(0, 255, 255), -1);
	//circle(src, srcPts[B_R], 10, Scalar(255, 0, 0), -1);
	//circle(src, srcPts[B_L], 10, Scalar(0, 255, 0), -1);

	

	double LeftHeight = EuDis(srcPts[T_L], srcPts[B_L]);
	double RightHeight = EuDis(srcPts[T_R], srcPts[B_R]);
	double MaxHeight = max(LeftHeight, RightHeight);

	double UpWidth = EuDis(srcPts[T_L], srcPts[T_R]);
	double DownWidth = EuDis(srcPts[B_L], srcPts[B_R]);
	double MaxWidth = max(UpWidth, DownWidth);

	Point2f SrcAffinePts[4] = { Point2f(srcPts[T_L]),Point2f(srcPts[T_R]) ,Point2f(srcPts[B_R]) ,Point2f(srcPts[B_L]) };
	Point2f DstAffinePts[4] = { Point2f(0,0),Point2f(MaxWidth,0),Point2f(MaxWidth,MaxHeight),Point2f(0,MaxHeight) };

	Mat M = getPerspectiveTransform(SrcAffinePts, DstAffinePts);

	Mat DstImg;
	warpPerspective(src, DstImg, M, Point(MaxWidth, MaxHeight));
	//imshow("Dst", DstImg);


	imshow("src", src);
	waiTKEy(0);
	destroyAllwindows();

	system("pause");
	return 0;
}

总结

本文使用OpenCV C++ 进行图像透视矫正,关键步骤有以下几点。

1、图像预处理,获取二值图像。

2、将二值图像进行轮廓提取,定位矩形四个角点,并确定其位置。

3、确定图像变换后的长、宽。并将SrcAffinePts、DstAffinePts一一对应之后进行透视变换。

到此这篇关于C++ OpenCV实战之图像透视矫正的文章就介绍到这了,更多相关C++ OpenCV图像透视矫正内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++OpenCV实战之图像透视矫正

本文链接: https://www.lsjlt.com/news/162075.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++OpenCV实战之图像透视矫正
    目录前言一、图像预处理二、轮廓提取1.提取最外轮廓2.提取矩形四个角点3.将矩形角点排序三、透视矫正四、源码前言 本文将使用OpenCV C++ 进行图像透视矫正。 一、图像预处理 ...
    99+
    2022-11-12
  • Python Opencv基于透视变换的图像矫正
    本文实例为大家分享了Python Opencv基于透视变换的图像矫正,供大家参考,具体内容如下 一、自动获取图像顶点变换(获取图像轮廓顶点矫正) 图像旋转校正思路如下 1、以灰度图读...
    99+
    2022-11-13
  • OpenCV如何通过透视变换实现矫正图像
    这篇“OpenCV如何通过透视变换实现矫正图像”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“OpenCV如何通过透视变换实现...
    99+
    2023-07-05
  • OpenCV怎么通过透视变换实现矫正图像
    这篇“OpenCV怎么通过透视变换实现矫正图像”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“OpenCV怎么通过透视变换实现...
    99+
    2023-07-05
  • OpenCV实现透视变换矫正
    本文实例为大家分享了OpenCV实现透视变换矫正的具体代码,供大家参考,具体内容如下 演示结果参考: 功能实现:运行程序,会显示图片的尺寸,按回车键后,依次点击需矫正的图片的左上、...
    99+
    2022-11-13
  • opencv+python实现图像矫正
    本文实例为大家分享了opencv+python实现图像矫正的具体代码,供大家参考,具体内容如下 需求:将斜着拍摄的文本图像进行矫正 python代码 import numpy as ...
    99+
    2022-11-11
  • 深入探讨opencv图像矫正算法实战
    摘要 在机器视觉中,对于图像的处理有时候因为放置的原因导致ROI区域倾斜,这个时候我们会想办法把它纠正为正确的角度视角来,方便下一步的布局分析与文字识别,这个时候通过透视变换就可以取...
    99+
    2022-11-12
  • OpenCV透视变换应用之书本视图矫正+广告屏幕切换
    目录一、透视变换的实际应用场景二、案例了解透视变换--书本视图矫正三、案例了解透视变换--广告屏幕切换一、透视变换的实际应用场景 我们在出门坐车时,经常会看到司机会使用一种行车辅助工...
    99+
    2022-11-13
    OpenCV 透视变换应用 OpenCV透视变换 OpenCV 视图矫正 OpenCV 屏幕切换
  • C++OpenCV实战之图像全景拼接
    目录前言一、OpenCV Stitcher1.功能源码2.效果二、图像全景拼接1.特征检测2.计算单应性矩阵3.透视变换4.图像拼接5.功能源码6.效果三、源码总结前言 本文将使用O...
    99+
    2022-11-12
  • C++OpenCV实战之制作九宫格图像
    目录前言一、九宫格图像二、源码三、效果显示总结前言 本文将使用OpenCV C++ 制作九宫格图像。其实原理很简单,就是将一张图像均等分成九份。然后将这九个小块按一定间隔(九宫格效果...
    99+
    2022-11-12
  • Python图像处理之透视变换的实战应用
    目录1 引言2 公式3 举例4 应用4.1 读入图像4.2 挑选源图四个点4.3 进行透视变换5 应用6 总结1 引言 如果你想对图像进行校准,那么透视变换是非常有效的变换手段。透视...
    99+
    2022-11-12
  • OpenCV和C++实现图像的翻转(镜像)、平移、旋转、仿射与透视变换
    目录一、翻转(镜像)二、仿射扭曲获取变换矩阵仿射扭曲函数 warpAffine旋转平移三、仿射变换四、透视变换综合示例总结官网教程 一、翻转(镜像) 头文件 quick_opencv...
    99+
    2022-11-12
  • OpenCV实战之图像拼接的示例代码
    目录背景实现步骤一、读取文件二、单应性矩阵计算三、图像拼接总结背景 图像拼接可以应用到手机中的全景拍摄,也就是将多张图片根据关联信息拼成一张图片; 实现步骤 1、读文件并缩放图片大小...
    99+
    2022-11-12
  • OpenCV实战记录之基于分水岭算法的图像分割
    目录0. 前言1. 分水岭算法2. 分水岭算法直观理解3. 完整代码总结0. 前言 分水岭变换是一种流行的图像处理算法,用于快速将图像分割成同质区域。分水岭变换主要基于以下思想:当图...
    99+
    2023-02-22
    opencv 分水岭算法 opencv图像分割算法 opencv 分水岭算法应用
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作