基于c++利用opencv编写程序实现调用计算机摄像头,并实现透视+二值化+细化+霍夫变换和角点的功能
时间: 2023-06-29 16:04:09 浏览: 166
以下是一个示例代码,实现了基于OpenCV的摄像头调用、透视变换、二值化、细化、霍夫变换和角点检测的功能:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 打开摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cerr << "Failed to open camera." << endl;
return -1;
}
// 读取棋盘格图像
Mat chessboardImg = imread("chessboard.png", IMREAD_GRAYSCALE);
if (chessboardImg.empty())
{
cerr << "Failed to read chessboard image." << endl;
return -1;
}
// 确定棋盘格角点
Size boardSize(9, 6);
vector<Point2f> chessboardCorners;
bool found = findChessboardCorners(chessboardImg, boardSize, chessboardCorners);
while (true)
{
// 读取当前帧
Mat frame;
cap >> frame;
if (frame.empty())
break;
// 透视变换
Mat warpedImg;
if (found)
{
// 计算透视变换矩阵
vector<Point2f> srcPoints, dstPoints;
for (int i = 0; i < boardSize.height; i++)
{
for (int j = 0; j < boardSize.width; j++)
{
srcPoints.push_back(Point2f(j * 50, i * 50));
dstPoints.push_back(chessboardCorners[i * boardSize.width + j]);
}
}
Mat H = findHomography(srcPoints, dstPoints);
// 进行透视变换
warpPerspective(frame, warpedImg, H, Size(400, 300));
}
else
{
warpedImg = frame;
}
// 二值化
Mat binaryImg;
cvtColor(warpedImg, binaryImg, COLOR_BGR2GRAY);
threshold(binaryImg, binaryImg, 0, 255, THRESH_OTSU);
// 细化
Mat thinImg;
thin(binaryImg, thinImg);
// 霍夫变换
vector<Vec2f> lines;
HoughLines(thinImg, lines, 1, CV_PI / 180, 50);
// 绘制直线
Mat lineImg = Mat::zeros(thinImg.size(), CV_8UC1);
for (size_t i = 0; i < lines.size(); i++)
{
float rho = lines[i][0], theta = lines[i][1];
double a = cos(theta), b = sin(theta);
double x0 = a * rho, y0 = b * rho;
Point pt1(cvRound(x0 + 1000 * (-b)), cvRound(y0 + 1000 * (a)));
Point pt2(cvRound(x0 - 1000 * (-b)), cvRound(y0 - 1000 * (a)));
line(lineImg, pt1, pt2, Scalar(255), 1, LINE_AA);
}
// 角点检测
vector<Point2f> corners;
goodFeaturesToTrack(thinImg, corners, 100, 0.01, 10);
for (size_t i = 0; i < corners.size(); i++)
{
circle(lineImg, corners[i], 3, Scalar(255), -1);
}
// 显示结果
imshow("frame", frame);
imshow("warped", warpedImg);
imshow("binary", binaryImg);
imshow("thin", thinImg);
imshow("lines", lineImg);
// 按下ESC键退出
if (waitKey(30) == 27)
break;
}
return 0;
}
```
需要注意的是,这里使用的棋盘格图像是一个9x6的标准棋盘格图像,如果你要使用其他类型的标定板,需要相应地修改代码中的变量`boardSize`。此外,角点检测和霍夫变换的参数也可以根据具体情况进行调整。
阅读全文