一、点拟合操作
拟合含义如上图,即为通过已知点去拟合一条直线或者一个多边形。
直线拟合函数:
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;
}