opencv_c++学习(二十三)

一、点拟合操作

在这里插入图片描述
拟合含义如上图,即为通过已知点去拟合一条直线或者一个多边形。

直线拟合函数:

fitLine(lnputArray points, OutputArray line, int distType, double param, double reps, double aeps)

points:输入待拟合直线的2D或者3D点集。
line:输出描述直线的参数,2D点集描述参数为Vec4f类型,3D点集描述参数为Vec6f类型。
distType: M-estimator算法使用的距离类型标志。
param:某些类型距离的数值参数©。如果数值为0,则自动选择最佳值。
reps:坐标原点与直线之间的距离精度,数值0表示选择自适应参数,一般常选择0.01。
acps:直线角度精度,数值0表示选择自适应参数,一般常选择0.01。
在这里插入图片描述

圆形拟合操作:

minEnclosingCircle(InputArray points, Point2f & center,float & radius)

points:待寻找包围圆形的2D点集。
center:圆形的圆心。
radius:圆形的半径。
三角形拟合操作:

minEnclosingTriangle(lnputArray points, OutputArray triangle)

points:待寻找包围三角形的2D点集。
triangle:拟合出的三角形三个顶点坐标。
本节应用案例如下:

int main() {
    
    

	//定义一个随机点图像
	Mat img(500, 500, CV_8UC3, Scalar::all(0));

	//生成随机点
	RNG& rng = theRNG();

	while (true)
	{
    
    
		int i, count = rng.uniform(1, 101);
		vector<Point>points;
		//生成随机点
		for ( i = 0; i < count; i++)
		{
    
    
			Point pt;
			pt.x = rng.uniform(img.cols / 4, img.cols * 3 / 4);
			pt.y = rng.uniform(img.rows / 4, img.rows * 3 / 4);
			points.push_back(pt);
		}

		//寻找包围点集的三角形
		vector<Point2f> triangle;
		minEnclosingTriangle(points, triangle);

		//寻找包围点集的圆形
		Point2f center;
		float radius = 0;
		minEnclosingCircle(points, center, radius);


		//输出图片
		img = Scalar::all(0);
		Mat img2;
		img.copyTo(img2);

		//在图像中绘制坐标点
		for ( i = 0; i < count; i++)
		{
    
    
			circle(img, points[i], 3, Scalar(255, 255, 255), FILLED, LINE_AA);
			circle(img2, points[i], 3, Scalar(255, 255, 255), FILLED, LINE_AA);
		}

		//绘制三角形
		for ( i = 0; i < 3; i++)
		{
    
    
			if (i == 2)
			{
    
    
				line(img, triangle[i], triangle[0], Scalar(255, 255, 255), 1, 16);
				break;
			}
			line(img, triangle[i], triangle[i + 1], Scalar(255, 255, 255), 1, 16);
		}

		//绘制圆形
		circle(img2, center, cvRound(radius), Scalar(255, 255, 255), 1, LINE_AA);

		//输出结果
		imshow("q", img);
		imshow("w", img2);

		//按ESC键退出程序
		char key = (char)waitKey();
		if (key == 27||key == 'q'||key=='Q')
		{
    
    
			break;
		}
	}
	return 0;
}

二、二维码的识别

在这里插入图片描述
二维码的定位函数:

detect (InputArray img, OutputArray points) const

img:待检测是否含有QR二维码的灰度图像或者彩色图像。
points:包含QR二维码的最小区域四边形的四个顶点坐标,即二维码的四个顶点坐标。
二维码识别函数:

QRCodeDetectore:decode(lnputArray img, lnputArraypoints, outputArray straight_qrcode = noArray())

img:含有QR二维码的图像。
points:包含QR二维码的最小区域四边形的四个顶点坐标。straight_qrcode:经过校正和二值化的QR二维码。
二维码定位与识别函数:

detectAndDecode(InputArray limg, OutputArray points = noArray(), OutputArray straight_qrcode = noArray())

img:含有QR二维码的图像。
points:包含QR二维码的最小区域四边形的四个顶点坐标。straight_qrcode:经过校正和二值化的QR二维码。

本节应用案例如下:

int main() {
    
    

	//读取图片
	Mat src = imread("3.jpg");
	if (src.empty())
	{
    
    
		printf("不能打开空图片");
		return -1;
	}

	//转化为灰度图
	Mat gray, qrcode_bin;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	QRCodeDetector qrcodeDetector;

	//存储坐标
	vector<Point> points;
	string information;
	bool isQRcode;

	//识别二维码
	isQRcode = qrcodeDetector.detect(gray, points);

	//对二维码进行解码操作
	if (isQRcode)
	{
    
    
		information = qrcodeDetector.decode(gray, points, qrcode_bin);

		//输出二维码四个顶点的坐标
		cout << points << endl;
	}

	else
	{
    
    
		return -1;
	}

	//绘制二维码边框
	for (int i = 0; i < points.size(); i++)
	{
    
    
		if (i == points.size()-1)
		{
    
    
			line(src, points[i], points[0], Scalar(0, 0, 255), 2, 8);
			break;
		}
		line(src, points[i], points[i+1], Scalar(0, 0, 255), 2, 8);
	}

	//将解码内容输出到图片上
	putText(src, information.c_str(), Point(20, 30), 0, 1.0, Scalar(0, 0, 255), 2, 8);

	//使用函数直接定位二维码并解码
	string information2;
	vector<Point> points2;
	information2 = qrcodeDetector.detectAndDecode(gray, points2);
	//输出二维码四个顶点的坐标
	cout << points << endl;
	//将解码内容输出到图片上
	putText(src, information2.c_str(), Point(20, 30), 0, 1.0, Scalar(0, 0, 255), 2, 8);

	imshow("q", src);
	imshow("w", WINDOW_NORMAL);
	imshow("e", qrcode_bin);

	waitKey(0);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_52302919/article/details/130875001