opencv矩形识别
程序员文章站
2022-04-03 16:51:17
...
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
using namespace cv;
using namespace std;
double angle(Point pt1, Point pt2, Point pt0)
{
double dx1 = pt1.x - pt0.x;
double dy1 = pt1.y - pt0.y;
double dx2 = pt2.x - pt0.x;
double dy2 = pt2.y - pt0.y;
return (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}//勾股定理验证是否满足直角的关系
void findRectInfo(std::vector<cv::Point> rect, int *rectInfo)
{
int x[4] = { 0 }, y[4] = { 0 };
int maxX = 0, maxY = 0, minX = 2000, minY = 2000;
//get the rect points
for (int i = 0; i<4; i++)
{
x[i] = rect[i].x;
y[i] = rect[i].y;
if (maxX<x[i])
maxX = x[i];
if (maxY<y[i])
maxY = y[i];
if (minX>x[i])
minX = x[i];
if (minY>y[i])
minY = y[i];
}
rectInfo[0] = minY;
rectInfo[1] = minX;
rectInfo[2] = maxY - minY;
rectInfo[3] = maxX - minX;
//cout << "minY=" << minY << endl;
//cout << "minX=" << minX << endl;
//cout << "maxY - minY=" << maxY - minY << endl;
//cout << "maxX - minX=" << maxX - minX << endl;
return;
}
int main()
{
Mat src = imread("755.jpg");
Mat binaryzation, gray, pengzhang, deaden, edge;
Mat dst = Mat::zeros(src.size(), CV_8UC3);
cvtColor(src, gray, CV_BGR2GRAY);
imshow("灰度", gray);
//erzhi.create(src.size(), src.type());
threshold(gray, binaryzation, 50, 255, THRESH_BINARY);
imshow("二值化", binaryzation);
Mat element = getStructuringElement(0, Size(2 + 1, 2 + 1), Point(1, 1)); // 构建内核
dilate(binaryzation, pengzhang, element, Point(-1, -1), 2); // 膨胀2次
imshow("膨胀", pengzhang);
blur(pengzhang, deaden, Size(3, 3));
imshow("降噪", deaden);
Canny(deaden, edge, 3, 9, 3);
imshow("轮廓", edge);
std::vector<std::vector<Point>> contours;
std::vector<Vec4i> hierarchy;
findContours(edge, contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
RNG rng(0);
std::vector<Point> approx;
std::vector<std::vector<Point>> squares;
for (int i = 0; i < contours.size(); i++)
{
//if (contours[i].size() < 10 || contours[i].size() > 100)
//{
// continue;
//}
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
if (approx.size() >= 4 &&
fabs(contourArea(Mat(approx))) > 1000 &&
isContourConvex(Mat(approx)))
{
printf("i = %d %d \n", i, approx.size());
// double maxCosine = 0; // 多边形逼近
// for (int j = 2; j < 5; j++)
// {
// double cosine = fabs(angle(approx[j % 4], approx[j - 2], approx[j - 1]));
// maxCosine = MAX(maxCosine, cosine);
// }
// if (maxCosine < 0.1)
// squares.push_back(approx);
int tmp[4] = { 0 };
findRectInfo(approx, tmp);
if (tmp[2] < 15 // 过滤出自己需要的轮廓
|| tmp[2] > 35
|| tmp[3] < 50
|| *tmp < 500)
{
continue;
}
printf("%d %d %d %d\n", *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3));
Scalar color = Scalar(255, 255, 255);
drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0, 0));
}
}
imshow("结果", dst);
imwrite("ab.jpg", dst);
waitKey();
return 0;
}
下一篇: 绝对定位与margin-bottom