zoukankan      html  css  js  c++  java
  • 网友提问—孔洞提取

    最近有网友咨询相关算法问题,我给了一些帮助,觉得比较典型,在经过他允许后将相关资料和思路进行整理,放出来大家共同学习!
    一、问题:
        图中这个孔是两个半圆加直线组成的,不同于普通的圆和椭圆,所以用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

  • 相关阅读:
    Hihocoder 1275 扫地机器人 计算几何
    CodeForces 771C Bear and Tree Jumps 树形DP
    CodeForces 778D Parquet Re-laying 构造
    CodeForces 785E Anton and Permutation 分块
    CodeForces 785D Anton and School
    CodeForces 785C Anton and Fairy Tale 二分
    Hexo Next 接入 google AdSense 广告
    如何统计 Hexo 网站的访问地区和IP
    Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple Task Points
    通过ODBC接口访问人大金仓数据库
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/8045769.html
Copyright © 2011-2022 走看看