使用OpenCV實現Halcon算法(3)選擇輪廓,select_shape

halcon源碼:ios

read_image (Image1, 'F:/將來項目/鋼管識別/FindTube/FindTube/1.jpg')
rgb1_to_gray (Image1, GrayImage)
threshold (GrayImage, Regions, 43, 111)
connection (Regions, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 150, 666)
select_shape (SelectedRegions, SelectedRegions1, 'circularity', 'and', 0.45, 1)

固然Halcon是在背後作了許多工做的。函數

幾行代碼中,比較重要的是算子就是"select_shape"。這個算子的參數不少,我也就比較熟悉這兩種。ui

若是我想在Opencv中也要這樣的結果,就須要本身動手嘗試實現。實現過程當中我採用了相似的函數名錶示敬意。spa

// selectshape.cpp : 選擇輪廓
// by: jsxyhelu(1755311380)
#include "stdafx.h"
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
#define  VP  vector<Point>  //用VP符號代替 vector<point>
RNG  rng(12345    );
//帶有上下限的threshold
void threshold2(Mat gray,Mat& thresh,int minvalue,int maxvalue)
{
    Mat thresh1;
    Mat thresh2;
    threshold(gray,thresh1,43,255, THRESH_BINARY);
    threshold(gray,thresh2,111,255,THRESH_BINARY_INV);
    thresh = thresh1 & thresh2;
}
//尋找並繪製出聯通區域
vector<VP> connection2(Mat src,Mat& draw)
{    
    draw = Mat::zeros(src.rows,src.cols,CV_8UC3);
    vector<VP>contours;    
    findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
    for (int i=0;i<contours.size();i++)
    {
        Scalar  color  = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
        drawContours(draw,contours,i,color,-1);
    }
    return contours;
}
//select_shape
vector<VP>  selectShapeArea(Mat src,Mat& draw,vector<VP> contours,int minvalue,int maxvalue)
{
    vector<VP> result_contours;
    draw = Mat::zeros(src.rows,src.cols,CV_8UC3);
    for (int i=0;i<contours.size();i++)
    { 
        int countour_area = contourArea(contours[i]);
        if (countour_area >minvalue && countour_area<maxvalue)
        {
            result_contours.push_back(contours[i]);
        }
    }
    for (int i=0;i<result_contours.size();i++)
    {
        Scalar  color  = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
        drawContours(draw,result_contours,i,color,-1);
    }
    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;
}
//select_shape
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(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
        drawContours(draw,result_contours,i,color,-1);
    }
    return result_contours;
}
int _tmain(int argc, _TCHAR* argv[])
{    
    Mat src;
    Mat gray;
    Mat thresh;
    Mat draw_connection;
    Mat draw_area;
    Mat draw_circle;
    vector<VP>contours_connection;    
    vector<VP>contours_area;
    vector<VP>contours_circle;
    vector<VP>contours_tmp;
    //read_image (Image1, 'F:/將來項目/鋼管識別/FindTube/FindTube/1.jpg')
    src = imread("1.jpg");
    //rgb1_to_gray (Image1, GrayImage)
    cvtColor(src,gray,COLOR_BGR2GRAY);
    //threshold (GrayImage, Regions, 43, 111)
    threshold2(gray,thresh,43,111);
    //connection (Regions, ConnectedRegions)
    contours_connection = connection2(thresh.clone(),draw_connection);
    //select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 150, 666)
    contours_area = selectShapeArea(thresh.clone(),draw_area,contours_connection,150,666);
    //select_shape (SelectedRegions, SelectedRegions1, 'circularity', 'and', 0.45, 1)
    contours_circle = selectShapeCircularity(thresh.clone(),draw_circle,contours_area,1,6);
    //顯示結果
    imshow("src",src);
    imshow("thresh",thresh);
    imshow("draw_connection",draw_connection);
    imshow("draw_area",draw_area);
    imshow("draw_circle",draw_circle);
    waitKey();
}
相關文章
相關標籤/搜索