用opencv识别一张图片里面特定形状面积占比,并且可用鼠标选择roi区域,用c++实现
时间: 2024-02-09 18:09:30 浏览: 82
好的,针对这个问题,我可以给出以下实现思路:
1.读取输入的图片并显示,等待用户用鼠标选择ROI区域。
2.将选择的ROI区域转换成灰度图像,并使用二值化处理。
3.使用形态学操作(膨胀、腐蚀、开运算、闭运算等)进行图像增强,以帮助识别特定形状。
4.使用findContours函数查找图像中的轮廓,并计算每个轮廓的面积。
5.筛选出特定形状的轮廓,并计算其面积占比。
下面是基于OpenCV 4.5.1的C++代码实现:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
// 读取输入的图片
Mat src = imread("input.jpg");
if (src.empty())
{
cout << "Could not open or find the image!\n" << endl;
return -1;
}
// 显示原始图像,并等待用户用鼠标选择ROI区域
imshow("Original Image", src);
Rect roi = selectROI("Select ROI", src, false, false);
// 将ROI区域转换成灰度图像
Mat gray;
cvtColor(src(roi), gray, COLOR_BGR2GRAY);
// 二值化处理
Mat binary;
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
// 形态学操作
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(binary, binary, MORPH_CLOSE, kernel);
// 查找轮廓
vector<vector<Point>> contours;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// 计算特定形状的面积占比
double area_all = 0, area_target = 0;
for (size_t i = 0; i < contours.size(); i++)
{
double area = contourArea(contours[i]);
if (area > 100) // 限制最小面积
{
double perimeter = arcLength(contours[i], true);
double circularity = 4 * CV_PI * area / (perimeter * perimeter);
if (circularity > 0.7 && circularity < 0.9) // 限制圆形度
{
area_all += area;
if (roi.contains(contours[i][0]))
{
area_target += area;
drawContours(src(roi), contours, i, Scalar(0, 0, 255), 2);
}
else
{
drawContours(src, contours, i, Scalar(0, 255, 0), 2);
}
}
}
}
double ratio = area_target / area_all * 100;
cout << "The ratio of target area to total area is: " << ratio << "%" << endl;
// 显示处理结果
imshow("Binary Image", binary);
imshow("Contours", src);
waitKey(0);
return 0;
}
```
在上述代码中,使用了selectROI函数来让用户使用鼠标选择ROI区域,并使用了drawContours函数来绘制轮廓。
需要注意的是,这只是一种实现思路,可能需要根据具体情况进行调整和优化。
阅读全文