Qt 搭配 OpenCv 尋找亮點,圈出物件

Step 1.

使用燈泡的照片尋找亮點,放到電腦指定的位置

位置 : C:\\light.jpg

Step 2.

判斷圖片是否存在

Mat src = imread("C:\\light.jpg");


if (src.empty())

{

    std::cout << "Could not load image file!";

    system("pause");

    return 0;

else {

    // 準備圈出物件

}

全域參數,後面會使用

Mat src, threshold_output;

Mat src_gray;

RNG rng(12345);


int erosion_elem = 0;

int erosion_size = 5;

int dilation_elem = 0;

int dilation_size = 10;

include

#include "mainwindow.h"

#include <QApplication>


#include "opencv2/highgui/highgui.hpp"

#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>

#include <stdio.h>

#include <stdlib.h>

#include <math.h>


#include <QDebug>


using namespace cv;

using namespace std;

Step 3.

轉成灰度圖及平滑化

Mat src_result = src.clone();


// 轉成灰度圖

cvtColor(src, src_gray, CV_BGR2GRAY);


// 平滑化

blur(src_gray, src_gray, Size(3,3));


// 均衡化直方圖(應加對比效果)

equalizeHist( src_gray, src_gray);


// 顯示視窗

namedWindow("Src_gray");

imshow("Src_gray", src_gray);


灰度圖

Step 4.

二值化

// 二值化

threshold( src_gray, threshold_output, 240, 255, THRESH_BINARY);


namedWindow("Undo Erode And Dilate");

imshow("Undo Erode And Dilate", threshold_output);


二值化

Step 5. 

腐蝕即膨脹,將太小的物件排除

void Erosion(int, void*);

void Dilation(int, void*);


void Erosion(int, void*)

{

    int erosion_type = 0;

    if (erosion_elem == 0) {

        erosion_type = MORPH_RECT;

    } else if (erosion_elem == 1) {

        erosion_type = MORPH_CROSS;

    } else if (erosion_elem == 2) {

        erosion_type = MORPH_ELLIPSE;

    }


    Mat element = getStructuringElement(erosion_type,

        Size(2 * erosion_size + 1, 2 * erosion_size + 1),

        Point(erosion_size, erosion_size));


    erode(threshold_output, threshold_output, element);

    imshow("Erosion", threshold_output);

}


void Dilation(int, void*)

{

    int dilation_type = 0;


    if (dilation_elem == 0) {

        dilation_type = MORPH_RECT;

    } else if (dilation_elem == 1){

        dilation_type = MORPH_CROSS;

    } else if (dilation_elem == 2) {

        dilation_type = MORPH_ELLIPSE;

    }


    Mat element = getStructuringElement(dilation_type,

        Size(2 * dilation_size + 1, 2 * dilation_size + 1),

        Point(dilation_size, dilation_size));


    dilate(threshold_output, threshold_output, element);

    imshow("Dilation", threshold_output);

}

Erosion

Erosion(0, 0);


腐蝕
Dilation

Dilation(0, 0);


膨脹

Step 6.

畫輪廓

vector<vector<Point> > contours, contoursFill;

vector<Vec4i> hierarchy;


findContours(threshold_output, contours, hierarchy,

     CV_RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0));


Mat drawing = Mat::zeros(src.size(), CV_8UC3);


int parentIdx=-1;

int k = 0;


for( int i = 0; i < contours.size(); i++ ) {

    parentIdx = i;

    contoursFill.push_back(contours[parentIdx]);


    // 畫輪廓

    drawContours(drawing, contours, parentIdx,  CV_RGB(rng.uniform(0,255), rng.uniform(0,255),             rng.uniform(0,255)) , 1, 8);

}


namedWindow("畫輪廓");

imshow("畫輪廓", drawing );


畫輪廓

Step 7.

填滿輪廓顏色

// 填滿輪廓顏色

for(int i = 0; i < contoursFill.size(); i++) {

    drawContours(drawingFill, contoursFill, i,  CV_RGB(rng.uniform(100,255),                          rng.uniform(100,255), rng.uniform(100,255)) , -1, 4, hierarchy[k][2], 0, Point() );

}


namedWindow("填滿輪廓顏色");

imshow("填滿輪廓顏色", drawingFill );


填滿輪廓顏色

Step 8.

圈出紅色方框

// 紅色方框顯示

Mat gray_all,threshold_output_all;

vector<vector<Point> > contours_all;

vector<Vec4i> hierarchy_all;

cvtColor( drawingFill, gray_all, CV_BGR2GRAY );


threshold( gray_all, threshold_output_all, 45, 255, THRESH_BINARY );


// RETR_EXTERNAL 尋找最外層

findContours( threshold_output_all, contours_all, hierarchy_all,  RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0) );


        for(int j = 0 ; j < contours_all.size() ; j++) {


            Point2f fourPoint2f[4];


            RotatedRect rectPoint = minAreaRect(contours_all[j]);


            rectPoint.points(fourPoint2f);


            for (int i = 0; i < 4 ; i++) {

                line(src_result, fourPoint2f[i%4], fourPoint2f[(i + 1)%4], 

                    Scalar(20,21,237), 3);

            }

        }


namedWindow("Result");

imshow("Result", src_result);


cvWaitKey();

return 0;


結果

Step 9.

調整腐蝕和膨脹參數,圈出單一個物件

調整參數

原本一個燈泡會圈出兩個物件,調整成圈出一個物件

結果

後記

如果這篇文章對於你有幫助,可以幫忙分享給更多的人.文章內容如果有誤,可以在下方留言告知.本網站主要提供程式, 玩具相關資訊,可以訂閱獲得最即時的資訊.

留言

熱門文章

Google Play Console 2022 上架資訊,審核通過時間

[ 教學 ] 如何使用 Sourcetree 對 Github 進行版本控制 #Mac OS 版本控制

2021申請 Android Developer 開發者帳號及上架步驟