OpenCV C++ 简单小技巧

查找和绘制轮廓findContours 会找到vector<vector<cv::Point>> contours;vector<Vec4i> hierarchy;f4 = Mat::zeros(frame.rows, frame.cols, CV_8UC3);f5 = Mat::zeros(frame.rows, frame.cols, CV_8UC3);findContours(f2, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, cv::Point());int idx=0;for( ; idx >= 0; idx = hierarchy[idx][0] ){ Scalar color( arc4random()&255, arc4random()&255, arc4random()&255 ); drawContours( f4, contours, idx, color, CV_FILLED, LINE_8, hierarchy ); drawContours( f5, contours, idx, color, 3, LINE_8, hierarchy );}// drawContours(f5, contours, -1, {0,255,0}, CV_FILLED, LINE_8);

threshold

morphologyEx+adaptiveThreshold如果在空mat上绘制,先把mat的区域设置好,填充满黑色。获得轮廓的矩形区域, 优化轮廓获得轮廓Moments m = moments(contours[idx]);质心int cx = int(m.m10/m.m00);int cy = int(m.m01/m.m00);面积 (面积小可以踢掉m.m00曲线优化 (epsilon百分比越低,越贴近原轮廓vector<cv::Point> approxCurve;double epsilon = 0.002*arcLength(contours[idx], true);approxPolyDP(contours[idx], approxCurve, epsilon, true);vector<vector<cv::Point>> poolApproxCurve;poolApproxCurve.push_back(approxCurve);drawContours( f5 , poolApproxCurve, 0, color, CV_FILLED, LINE_8 );

image.png凸包 hull将所有点囊括在内convexHull(contours[idx], approxCurve,false,true);for (int i=0; i<approxCurve.size(); i++) { circle(f3, approxCurve[i], 2, Scalar(255),30);}

image.png

image.png简化

image.png

image.png

image.png获得外切矩形 和 最小外切矩形(带旋转外框cv::Rect r = boundingRect(approxCurve);rectangle(f5, {r.x,r.y}, {r.x+r.width,r.y+r.height}, color,5);旋转外框cv::RotatedRect rr = minAreaRect(approxCurve);Mat boxPoints2f,boxPointsCov;boxPoints(rr, boxPoints2f);boxPoints2f.assignTo(boxPointsCov,CV_32S);polylines(f5, boxPointsCov, true,color,5);

image.png获得外切圆 和 外切椭圆外切圆Point2f pot;float radius;minEnclosingCircle(approxCurve, pot, radius);circle(f5, pot, radius, color,5);外切椭圆RotatedRect re = fitEllipse(approxCurve);ellipse(f5, re, color,5);

image.png拟合直线Vec4f lineData;fitLine(approxCurve, lineData, DIST_L2, 0, 0.01, 0.01);int lefty = (-lineData[2]*lineData[1]/lineData[0])+lineData[3];int righty = ((f5.cols-lineData[2])*lineData[1]/lineData[0])+lineData[3];line(f5, cv::Point(f5.cols-1,righty),cv::Point(0,lefty), color, 10);

image.pnghttps://stackoverflow.com/questions/14184147/detect-lines-opencv-in-object生成垂线double nx = 1;double ny = -lineData[0]/lineData[1];double mag = sqrt(1+ny*ny);lineData[0] = nx/mag;lineData[1] = ny/mag;lefty = (-lineData[2]*lineData[1]/lineData[0])+lineData[3];righty = ((f5.cols-lineData[2])*lineData[1]/lineData[0])+lineData[3];line(f5, cv::Point(f5.cols-1,righty),cv::Point(0,lefty), color, 10);

image.png凸缺陷 / 凹陷特征这里要注意的是 convexHull 这个函数输出hull特征时可以输出两种类型 vector<cv::Point> 和 vector<int>。如果用于之前凸包点显示则用point的数组, 如果用于凸缺陷则需要int数组,否则 convexityDefects 无法执行通过。输出的点也包含四个id信息,形状的位置点索引(开始点,结束点,以及凹陷内点)和深度(了解这个值的意义请留言)。另外做凸缺陷处理最好对目标简化,再进行,否则会出现很多数据。凸缺陷并非连续,他只是一些特征,如果是一个完全的圆,那么可能它没有任何缺陷,而矩形的缺陷就是它的四个边的中点。vector<int> hull2;convexHull(approxCurve, hull2,false,false);vector<Vec4i> defects;convexityDefects(approxCurve, hull2, defects);for (int i=0; i<defects.size(); i++) { Vec4i v = defects[i]; float depth = v[3]; if (depth > 10) { int startidx = v[0]; cv::Point ptStart(approxCurve[startidx]); int endidx = v[1]; cv::Point ptEnd(approxCurve[endidx]); int faridx = v[2]; cv::Point ptFar(approxCurve[faridx]); line(f3, ptStart, ptEnd, color, 5); circle(f3, ptFar, 30, color, -1); }}

image.pnghttps://stackoverflow.com/questions/31354150/opencv-convexity-defects-drawing比较两个轮廓NSLog(@"match %f",matchShapes(contours[idx], approxCurve, CONTOURS_MATCH_I1, 0));这里为进行比较了直接输出轮廓 和 简化后的轮廓比较,当两个相互接近时就趋近于0。轮廓的搜索方式类型方式图RETR_LIST将所有特征都列出来,无层次关系

image.pngRETR_EXTERNAL只返回外部轮廓

image.pngRETR_CCOMP只有一级父子, 内部如果有轮廓再生成父子关系

image.png

image.pngRETR_TREE所有等级关系[图片上传中...(image.png-3c7b3-1533915625653-0)]只遍历第一层 for(int idx=0 ; idx >= 0; idx = hierarchy[idx][0] )遍历所有轮廓 for (int idx=0; idx< contours.size(); idx++)扩展 (python代码,未进行验证)长宽比 w/hx,y,w,h = cv2.boundingRect(cnt)aspect_ratio = float(w)/h轮廓面积与边界矩形面积比 extentarea = cv2.contourArea(cnt)x,y,w,h = cv2.boundingRect(cnt)rect_area = w*hextent = float(area)/rect_area轮廓面积与凸包面积比 solidityarea = cv2.contourArea(cnt)hull = cv2.convexHull(cnt)hull_area = cv2.contourArea(hull)solidity = float(area)/hull_area获得轮廓面积相等的圆的直径area = cv2.contourArea(cnt)equi_diameter = np.sqrt(4*area/np.pi)方向(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)最大最小值和它们的位置min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)平均颜色及平均灰度min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)极点leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])topmost = tuple(cnt[cnt[:,:,1].argmin()][0])bottommost = tuple(cnt[cnt[:,:,1].argmax()][0]点到轮廓的最小距离第三个参数设置为true进行距离计算,false则判断返回+/-1和0这样的模糊量。dist = cv2.pointPolygonTest(cnt,(50,50),True)

(0)

相关推荐

  • 基于OpenCV的手掌检测和手指计数

    重磅干货,第一时间送达 利用余弦定理使用OpenCV-Python实现手指计数与手掌检测. 手检测和手指计数 接下来让我们一起探索以下这个功能是如何实现的. OpenCV OpenCV(开源计算机视觉 ...

  • 基于OpenCV的车辆变道检测

    重磅干货,第一时间送达 本期教程我们将和小伙伴们一起研究如何使用计算机视觉和图像处理技术来检测汽车在行驶中时汽车是否在改变车道!大家一定听说过使用OpenCV 的haar级联文件可以检测到面部.眼睛等 ...

  • 图像特征之傅里叶描述子

    使用C++.opencv获取轮廓的傅里叶描述子 傅里叶描述子是一种图像特征,具体来说,是一个用来描述轮廓的特征参数.其基本思想是用物体边界信息的傅里叶变换作为形状特征,将轮廓特征从空间域变换到频域内, ...

  • 【OpenCV读取标记点坐标】管道测速

    文章目录 一.项目简介 二.思考步骤 1. 图像二值化 2. 滤波去噪 3. Canny算法检测边缘 4. 查找轮廓并计算 5. 绘制轮廓并表示质心 三.测试结果 四.工程代码 一.项目简介 昨天一个 ...

  • OpenCV探索之路(十一):轮廓查找和多边形包围轮廓

    Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体.所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓. OpenCV中有一个很强大的函数,它可以从 ...

  • OPENCV之寻找并绘制轮廓以及提取轮廓重心坐标

    OPENCV之寻找并绘制轮廓以及提取轮廓重心坐标 1.寻找轮廓 声明:在寻找图像轮廓之前需要对图像进行阈值分割或者Canny.拉普拉斯等边缘检测算子处理. 寻找轮廓的算子: findContours( ...

  • opencv笔记(二十九)——提取轮廓相关函数使用方法

    opencv中常用的跟轮廓相关的操作有:findContours()查找轮廓:drawContours()画轮廓:轮廓填充:计算轮廓的面积和周长:提取轮廓凸包,矩形,最小外接矩形,外接圆等.它们都有相 ...

  • 帮助业余选手涨球的简单小技巧

             很多人在打乒乓球的时候把重点放在一些技术和战术的应用上面,这样做不是说不对,而是提醒大家技战术学习应用的同时,不要忽略了打球中一些小技巧的应用. 1. "照着来球收小臂&q ...

  • 如何打发全蛋?学会3个简单小技巧,轻松打发全蛋液零失败

    如何打发全蛋?学会3个简单小技巧,轻松打发全蛋液零失败

  • 简单小技巧,造就切开后的惊艳!

    我相信,每个人第一次看到漩涡蛋糕的切面时,绝对会被它给惊艳到! 只要将它切开,就绝对会有人上前问道:"这蛋糕难做吗?过程很复杂吧?" 制作抹茶漩涡蛋糕材料不需要特别的,制作过程一点 ...

  • 简单小技巧鉴别新老古玉(供藏友参考)

    要想学会鉴定古玉 古代砣工和现代电动工具加工痕迹的区别是必须掌握的基本技能 具体怎么区分 用最通俗的语言结合自己的实际经验给藏友分享一下 供大家参考,不足之处敬请谅解! 古代是利用砣具带动松散的解玉砂 ...

  • 蒜香黄油烤土豆,简单小技巧做出完美的酥脆口感,好吃到停不下来

    蒜香黄油烤土豆,简单小技巧做出完美的酥脆口感,好吃到停不下来

  • mountaindog1-三个简单小技巧练大肩膀!

    这期视频继续之前梅叔的<三个简单小技巧>系列,这一次讲解的内容是肩部训练!感兴趣的小伙伴千万不要错过! 肩膀训练技巧#1 高次数做后束训练 三角肌后束对于肩膀整体的形状以及肩关节功能都是非 ...

  • 教你在家自制薯片,几个简单小技巧,香脆零食就做好

    说起薯片这种零食,可以说是家喻户晓了,薯片含油量通常在30%左右,属高油高盐食物,与其他油炸食品是类似的,常吃对身体健康无益. 不过,即使有风险,仍然无法阻挡大家对美食的需求,在商场超市总是能看到各种 ...

  • 九个简单小技巧,就可以在小面积种植大量蔬菜

    每周5个永续美好生活类视频 60秒解读: 1.中国人到哪里都喜欢种菜,我想这是值得骄傲的事情,这是我们农耕民族与自然合作的生活智慧.只是在城里生活的人,没有土地,只有有限的空间. 2.本期视频的作者帕 ...

  • 简单小技巧+趁手清洁工具,我家房子住了7年,每天干干净净!

    做久了家居博主,就会越来越意识到简化家务的必要性. 我搬新家7年,尝试过无数的清洁技巧.神器,最终得到今天要给大家介绍的这套"简单技巧+趁手工具"的清洁方案. 现在我家除了日常小扫 ...