opencv绘制图形轮廓并筛选面积操作

1、 类比halcon的筛选区域面积的操作select_shape算子,opencv也可以对图形的轮廓进行面积的筛选,剔除无效区域。

int main()
{
Mat srcImage = imread("D:\\Opencv\\Project\\ConnectionProject\\modules_08.png");
imshow("【原图】", srcImage);

//首先对图像进行空间的转换  
Mat grayImage;
cvtColor(srcImage, grayImage, CV_BGR2GRAY);
//对灰度图进行滤波  
GaussianBlur(grayImage, grayImage, Size(3, 3), 0, 0);
imshow("【滤波后的图像】", grayImage);

//为了得到二值图像,对灰度图进行边缘检测  
Mat cannyImage;
Canny(grayImage, cannyImage, 128, 255, 3);
//在得到的二值图像中寻找轮廓  
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(cannyImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));


//绘制轮廓  
for (int i = 0; i < (int)contours.size(); i++)
{
drawContours(cannyImage, contours, i, Scalar(255), 1, 8);
}
imshow("【处理后的图像】", cannyImage);


//计算轮廓的面积  
cout << "【筛选前总共轮廓个数为】:" << (int)contours.size() << endl;
for (int i = 0; i < (int)contours.size(); i++)
{
double g_dConArea = contourArea(contours[i], true);
cout << "【用轮廓面积计算函数计算出来的第" << i << "个轮廓的面积为:】" << g_dConArea << endl;
}

//筛选剔除掉面积小于100的轮廓
vector <vector<Point>>::iterator iter = contours.begin();
for (; iter != contours.end();)
{
double g_dConArea = contourArea(*iter);
if (g_dConArea < 100)
{
iter = contours.erase(iter);
}
else
{
++iter;
}
}
cout << "【筛选后总共轮廓个数为:" << (int)contours.size() << endl;
for (int i = 0; i < (int)contours.size(); i++)
{
double g_dConArea = contourArea(contours[i], true);
cout << "【用轮廓面积计算函数计算出来的第" << i << "个轮廓的面积为:】" << g_dConArea << endl;
}
Mat result(srcImage.size(), CV_8U, Scalar(0));
drawContours(result, contours, -1, Scalar(255), 1);   // -1 表示所有轮廓  
namedWindow("result");
imshow("result", result);
waitKey(0);
return 0;

}

筛选前和筛选后的面积对比:

控制台输出数据:第一次轮廓面积个数为295,第二次筛选后面积个数为145,注意这里轮廓面积有正有负。

这里重点是2个算子,findcontours和drawcontours

//! retrieves contours and the hierarchical information from black-n-white image.
CV_EXPORTS_W void findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset=Point());

Image必须为二值图,可以通过compare(),inRange(),threshold(),adaptiveThreshold(),Canny()这些算子来实现对原图的二值化。

contours为输出的轮廓数组,每一个轮廓用Point类型的vector容器表示。

hierarchy参数和轮廓个数相同,每一个轮廓contour[i]都包含着hieracrchy[i][0],hieracrchy[i][1],hieracrchy[i][2],hieracrchy[i][3],分别表示前一个轮廓,后一个轮廓,父轮廓,内嵌轮廓的索引编号。

mode 表示轮廓的检索模式;

RETR_EXTERNAL表示只检索最外延的轮廓。

RETR_LIST表示检测的轮廓不建立等级关系

RETR_CCOMP建立两个等级的轮廓,上面一层为外边界,里面一层为内孔边界信息,如果孔内还有一个联通物体,这个物体的边界也在顶上,

RETR_TREE建立一个等级树的轮廓,这个实例中采用这种方法。

method表示轮廓的逼近方法

CHAIN_APPROX_NONE存储所有的轮廓点,相邻两个轮廓点的位置差不超过1,

CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形只保留4个点来保存轮廓信息。

CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法 offset表示轮廓的偏移数据,可以设定任何值,在ROI中寻找轮廓,并要在这个图像中分析时,还是很有用的。

//! draws contours in the image

CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours,
                              int contourIdx, const Scalar& color,
                              int thickness=1, int lineType=8,
                              InputArray hierarchy=noArray(),
                              int maxLevel=INT_MAX, Point offset=Point() );

contouridx指明画第几个轮廓,如果该参数为负数,-1,则画全部轮廓,

color为轮廓的颜色

thickness为轮廓的线宽,如果为负数或者CV_FILLED表示轮廓内部填充。

linetype表示线型

//绘制轮廓  
for (int i = 0; i < (int)contours.size(); i++)
{
drawContours(cannyImage, contours, i, Scalar(255), 1, 8);
}
imshow("【处理后的图像】", cannyImage);

等效于以下代码:

Mat result(srcImage.size(), CV_8U, Scalar(0));
drawContours(result, contours, -1, Scalar(255), 1);   // -1 表示所有轮廓  
--------------------- 
作者:RobotHeartGo  
原文:https://blog.csdn.net/wuguanghao/article/details/69941598 
 

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用OpenCV绘制图形可以通过调用不同的函数来实现。在Python中,可以使用cv2.line()来绘制线段,cv2.rectangle()来绘制矩形,cv2.circle()来绘制圆形,cv2.ellipse()来绘制椭圆,cv2.polylines()来绘制多边形,以及cv2.putText()来绘制文本。这些函数可以在计算机视觉任务和图像处理中非常有用。例如,可以使用cv2.circle()函数绘制圆形。 在OpenCV中,绘制图形的步骤通常包括创建一个画布,并在其上使用相应的函数绘制所需的图形。通过指定参数如颜色、线条宽度和填充等,可以对图形进行进一步的定制。例如,可以指定圆心坐标、半径和颜色来绘制一个圆形。 下面是一个示例代码,展示了如何使用OpenCV绘制图形: #include <opencv2/opencv.hpp> using namespace cv; int main() { // 载入图片 Mat srcImage = imread("dota.jpg", 1); Mat dstImage; // 转换颜色空间 cvtColor(srcImage, dstImage, COLOR_BGR2Lab); // 显示效果图 imshow("效果图", dstImage); waitKey(0); } 这个示例代码使用了cv2的imread()函数来载入一张图片,然后使用cvtColor()函数将图片转换为Lab颜色空间。最后,使用imshow()函数显示转换后的效果图。 希望这个回答能够帮助您了解如何使用OpenCV绘制图形。如果还有其他问题,请随时提问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【CV 向】OpenCV 图形绘制指南](https://blog.csdn.net/qq_21484461/article/details/131333236)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [OpenCV—学习基本绘图](https://blog.csdn.net/qq_44859533/article/details/125160651)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值