計算連通區域的像素點個數,找目標圓點

任務
圈出小圓點,不能圈不規則白點

參考知識
http://blog.csdn.net/qq_16540387/article/details/78844965
http://blog.csdn.net/qq_16540387/article/details/78843936
源碼

//------------------------------------------------------------------------------------------------
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;

#define WINDOW_NAME "【程序窗口】"        //爲窗口標題定義的宏 

double area;//輪廓面積
int g_nThresholdValue = 131;//二值化閾值
int g_nThresholdType = 3;
double minarea = 378;//目標輪廓最小像素點個數
double maxarea = 478;//目標輪廓最大像素點個數
Moments mom; // 輪廓矩  
Mat image, gray, edge, dst, g_srcImage1, dst1,g_srcImage,g_grayImage,g_dstImage;

vector<vector<Point> > contours;   //輪廓數組  
vector<Point2d>  centers;    //輪廓質心座標   
vector<vector<Point> >::iterator itr;  //輪廓迭代器  
vector<Point2d>::iterator  itrc;    //質心座標迭代器  
vector<vector<Point> > con;    //當前輪廓  
Point2d center;//質心座標

void on_Threshold(int, void*);//回調函數

int main()
{

    //【1】讀入源圖片
    g_srcImage = imread("pos71_run7_img190.jpg");

    //resize(g_srcImage, g_srcImage1, Size(g_srcImage.cols / 4, g_srcImage.rows / 4), 0, 0, INTER_LINEAR);
    //imshow("原始圖", g_srcImage1);

    cvtColor(g_srcImage, g_grayImage, COLOR_RGB2GRAY);//灰度轉換

    namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);

    createTrackbar("模式",
        WINDOW_NAME, &g_nThresholdType,//二值化模式
        4, on_Threshold);

    createTrackbar("參數值",
        WINDOW_NAME, &g_nThresholdValue,//二值化閾值 
        255, on_Threshold);

    on_Threshold(0, 0);//滑動條回調函數

    while (1)
    {
        int key;
        key = waitKey(20);
        if ((char)key == 27){ break; }
    }

}


void on_Threshold(int, void*)
{
    //調用閾值函數
    threshold(g_grayImage, g_dstImage, g_nThresholdValue, 255, CV_THRESH_BINARY);

    //resize(g_dstImage, g_srcImage1, Size(g_dstImage.cols / 4, g_dstImage.rows / 4), 0, 0, INTER_LINEAR);
    //imshow("threshold", g_srcImage1);

    Mat element2 = getStructuringElement(MORPH_RECT, Size(10, 10));//膨脹模板
    Mat erode1, erode2;
    dilate(g_dstImage, erode1, element2);//膨脹
    dilate(erode1, erode2, element2);

    //resize(erode2, g_srcImage1, Size(erode2.cols / 4, erode2.rows / 4), 0, 0, INTER_LINEAR);
    //imshow("dilate", g_srcImage1);

    findContours(erode2, contours,
        CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);//找出輪廓

    itr = contours.begin();     //使用迭代器去除非目標輪廓  
    while (itr != contours.end())
    {
        area = contourArea(*itr);//計算面積

        if ((area<minarea) | (area>maxarea))
        {
            itr = contours.erase(itr);  //刪除
        }
        else
        {
            itr++;
        }
    }

    dst = Mat::zeros(erode2.rows, erode2.cols, CV_8UC3);//保存中間結果
    itr = contours.begin();
    while (itr != contours.end())
    {
        area = contourArea(*itr);
        con.push_back(*itr);

        //cout << "\nb " << area;
        drawContours(dst, con, -1, Scalar(255, 0, 0), 2);   //目標區域藍色繪製  
        mom = moments(*itr);   //計算質心
        center.x = (int)(mom.m10 / mom.m00);
        center.y = (int)(mom.m01 / mom.m00);
        char tam[10000];
        char sam[10000];
        sprintf(tam, "(%0.0f)", area);
        sprintf(sam, "(%0.0f,%0.0f)", center.x, center.y);
        putText(dst, tam, Point(center.x, center.y), FONT_HERSHEY_SIMPLEX, 2, Scalar(255, 0, 0), 5);//標出面積
        putText(dst, sam, Point(center.x, center.y + 80), FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 255, 0), 5);//標出質心
        //imwrite("20003.jpg", dst);
        //resize(dst, dst1, Size(dst.cols / 4, dst.rows / 4), 0, 0, INTER_LINEAR);
        //imshow("中間結果", dst1);
        circle(g_srcImage, Point(center.x, center.y), 5, Scalar(0, 225, 0), 2, 3);//畫圓

        con.pop_back();

        itr++;
    }

    resize(g_srcImage, g_srcImage1, Size(g_srcImage.cols / 4, g_srcImage.rows / 4), 0, 0, INTER_LINEAR);
    //更新效果圖
    imshow(WINDOW_NAME, g_srcImage1);
    //imwrite("s_pos71_run7_img190.jpg", g_srcImage);
}

實驗結果

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章