网友提问—孔洞提取

最近有网友咨询相关算法问题,我给了一些帮助,觉得比较典型,在经过他允许后将相关资料和思路进行整理,放出来大家共同学习!

一、问题:

图中这个孔是两个半圆加直线组成的,不同于普通的圆和椭圆,所以用hough变换检测效果不好,有没有什么方法可以把那个孔的轮廓给提取出来?

二、分析和解体:
    如果对hough的原理和使用比较了解的话(可以翻看《学习OpenCV》),就知道想利用houghcircle取出这样的轮廓使不可能的,此类问题首先是要把关键区域强化出来,然后可以考虑轮廓分析的方法。

基于基础算法,做到目前程度。取这样一个洞的图像,很容易被阴影干扰,需要在图片采集的时候有所注意。
connection图
 

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "GOCVHelper.h"

using namespace cv;
using namespace std;
using namespace GO;
RNG  rng2(12345);
//根据轮廓的圆的特性进行选择
vector<VP>  selectShapeCircularity(Mat src,Mat& draw,vector<VP> contours,float minvalue,float maxvalue);
vector<VP>  selectShapeCircularity(vector<VP> contours,float minvalue,float maxvalue);
//计算轮廓的圆的特性
float calculateCircularity(VP contour);
//根据轮廓的圆的特性进行选择
vector<VP> selectShapeCircularity(Mat src,Mat& draw,vector<VP> contours,float minvalue,float maxvalue){
    vector<VP> result_contours;
    draw = Mat::zeros(src.rows,src.cols,CV_8UC3);
    for (int i=0;i<contours.size();i++){
        float fcompare = calculateCircularity(contours[i]);
        if (fcompare >=minvalue && fcompare <=maxvalue)
            result_contours.push_back(contours[i]);
    }
    for (int i=0;i<result_contours.size();i++){
        Scalar  color  = Scalar(rng2.uniform(0,255),rng2.uniform(0,255),rng2.uniform(0,255));
        drawContours(draw,result_contours,i,color,-1);
    }
    return result_contours;
}
vector<VP> selectShapeCircularity(vector<VP> contours,float minvalue,float maxvalue){
    vector<VP> result_contours;
    for (int i=0;i<contours.size();i++){
        float fcompare = calculateCircularity(contours[i]);
        if (fcompare >=minvalue && fcompare <=maxvalue)
            result_contours.push_back(contours[i]);
    }
    return result_contours;
}
//计算轮廓的圆的特性
float calculateCircularity(VP contour){
    Point2f center;
    float radius = 0;
    minEnclosingCircle((Mat)contour,center,radius);
    //以最小外接圆半径作为数学期望,计算轮廓上各点到圆心距离的标准差
    float fsum = 0;
    float fcompare = 0;
    for (int i=0;i<contour.size();i++){   
        Point2f ptmp = contour[i];
        float fdistenct = sqrt((float)((ptmp.x - center.x)*(ptmp.x - center.x)+(ptmp.y - center.y)*(ptmp.y-center.y)));
        float fdiff = abs(fdistenct - radius);
        fsum = fsum + fdiff;
    }
    fcompare = fsum/(float)contour.size();
    return fcompare;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //读入灰度的手部图像
    Mat src = imread("e:/sandbox/kong.jpg");
    Mat dst = src.clone();
    Mat tmp;
    Mat draw;
    vector<VP> contours;
    vector<VP> results;
    vector<Mat> planes;
    cvtColor(src,src,COLOR_BGR2HSV);
    split(src,planes);
    //v通道
    tmp = planes[2].clone();
    //去除毛刺
    GaussianBlur(tmp,tmp,Size(3,3),0);
    //阈值处理
    threshold(tmp,tmp,100,255,THRESH_OTSU);
    //反向
    bitwise_not(tmp,tmp);
    //形态学
    erode(tmp,tmp,Mat());
    dilate(tmp,tmp,Mat());
    //绘制联通区域
    contours = GO::connection2(tmp,draw);
    //轮廓分析(圆特性)
    results = selectShapeCircularity(tmp,draw,contours,    100,500);
    //原图绘制
    drawContours(dst,results,0,Scalar(0,0,255),3);
    imshow("result",dst);
    waitKey();
    return 0;
}

所用gocvhelpe可以在我的github https://github.com/jsxyhelu 上找到,我的博客地址为jsxyhelu.cnblogs.com

时间: 2024-11-09 03:54:57

网友提问—孔洞提取的相关文章

Jerry答网友提问:SAP CRM WebClient UI里的EXT,STRUCT等含义

2020年,Jerry会做一个新的尝试,选择部分朋友向我提出的问题,在公众号,知识星球或者微信圈子这些平台上公开回答,这样或许能帮助到更多的朋友. 具体说明参见我前一篇文章:2020年关于SAP知识问答的一个新的尝试 网友的提问: Jerry的解答: 以上截图是CRM系统里BSP_WD_CPMWB这个事务码进入之后,任意打开一个上下文节点(Context Node)看到的信息: STRUCT的含义? 在Jerry之前的文章 Jerry的WebClient UI 42篇原创文章合集 提到这样一张图

【转】如何在Qt 4程序中优化布局结构-兼回答网友提问

在迄今为止讲到每一个例子中,我们只是简单的把窗口部件放置到某个确定的布局中.但在某些情况下,由此形成的布局看起来可能还不是我们最想要的形式.在这些情形中,可以通过改变要摆放的窗口部件的大小策略和大小提示来调整布局. 1.大小提示(size hint)和最小大小提示(minimum size hint) 在介绍Qt窗口部件的大小策略之前,首先介绍大小提示(size hint)和最小大小提示(minimum size hint). ⑴ 大小提示 大小提示是Qt为一个窗口部件推荐的尺寸.当Qt GUI

如何在Qt 4程序中优化布局结构-兼回答网友提问(转帖)

在迄今为止讲到每一个例子中,我们只是简单的把窗口部件放置到某个确定的布局中.但在某些情况下,由此形成的布局看起来可能还不是我们最想要的形式.在这些情形中,可以通过改变要摆放的窗口部件的大小策略和大小提示来调整布局. 1.大小提示(size hint)和最小大小提示(minimum size hint) 在介绍Qt窗口部件的大小策略之前,首先介绍大小提示(size hint)和最小大小提示(minimum size hint). ⑴ 大小提示 大小提示是Qt为一个窗口部件推荐的尺寸.当Qt GUI

网友提问(透视变化)

您好: 我在网上看到您的opencv透视变换的博客,https://www.cnblogs.com/jsxyhelu/p/4219564.html, 我是opencv小菜鸟一个,现在想要得到一个图片变形之后保存,整个图片信息不丢失,即四个角的信息不丢失应该怎么做?原图中某一点在新图中坐标应该怎么计算?万望不吝赐教,不胜感激,万分感谢. 你好: 我按照您的代码和网上找到的python代码(https://blog.csdn.net/fengxueniu/article/details/779643

冯提莫上综艺节目又不好好穿衣服了,网友:胆子真大!

冯提莫上综艺节目又不好好穿衣服了,网友:胆子真大!https://travel.weibo.com/a/2309404227194841870073冯提莫上综艺节目又不好好穿衣服了,网友:胆子真大!https://weibo.com/p20180411Pp/2309404227194841870073冯提莫上综艺节目又不好好穿衣服了,网友:胆子真大!https://travel.weibo.com/a/2309404227194875458844冯提莫上综艺节目又不好好穿衣服了,网友:胆子真大!

我从事过的设计(文件夹)

我的工作:设计(解决方式) . 包含软件和硬件或由软件+硬件组成的系统 . 下面将介绍我几十年来从事过各种设计,包含为教学.科研和生产进行的设计.个人业余爱好设计,以及为社会或他人提供的义务设计,因这些设计都是为解决某个问题而思考出来的办法,所以也可称为解决方式. 设计包含软件和硬件,也有软硬一起构成的系统.硬件设计包含功能.逻辑.线路.PCB(印刷线路板).设备总体外形等,都要一一考虑,大都在上世纪60-70年代.80年代后都为软件系统设计,当中80年是在PDP11或VAX750等小型机上用F

PowerQuery实战:数据转置的综合应用

(正文开始)本案例来源于网友提问.案例描述:如上图,原格式为数据源,目标格式为需通过PowerQuery整理后的数据结构.大家可以先想一想,或者试一试,看是否可解决,在看了我以下的思路后,欢迎交流. 分析原格式与目标格式,形成以下思路:1.5行作为一组2.每组进行转置无论是写程序,还是通过软件操作,核心的步骤就这2步.以下是在PowerBI中操作说明与截图1.载入数据,如下图(步骤略)2.由于5行作为一组,所以需要新增辅助列,以下2步完成此操作.先新增索引列,如图:3.索引列的值除以5,然后取余

[廖雪峰] Git 分支管理策略

通常,合并分支时,如果可能,Git 会用 Fast forward 模式,但这种模式下,删除分支后,会丢掉分支信息. 如果要强制 禁用 Fast forward 模式,Git 就会在 merge 时生成一个新的 commit,这样,从分支历史上就可以看出分支信息. 下面我们实战一下 --no-ff 方式的 git merge: 首先,仍然创建并切换 dev 分支: $ git checkout -b dev Switched to a new branch 'dev' 修改 readme.txt

Python集合(set)类型的操作

python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算. sets 支持 x in set, len(set),和 for x in set.作为一个无序的集合,sets不记录元素位置或者插入点.因此,sets不支持 indexing, slicing, 或其它类序列(sequence-l