OpenCV和C++,檢測圖像輪廓,並用矩形把輪廓框起來

1.目標

用OpenCV和C++,檢測圖像輪廓,並用矩形把輪廓框起來。

昨天熬夜到凌晨2點看電視劇,當時覺得不應該,但還是熬夜了。
今天遭到了一萬點的暴擊,整個人都不好了,工作效率爲負。
每個人的健康狀態都不一樣,一定不要挑戰自己的健康極限。
以此爲戒:以後絕不熬夜!!!

2.代碼

//---------------------------------【頭文件、命名空間包含部分】----------------------------
//        描述:包含程序所使用的頭文件和命名空間
//------------------------------------------------------------------------------------------------
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;


//-----------------------------------【宏定義部分】-------------------------------------------- 
//        描述:定義一些輔助宏 
//------------------------------------------------------------------------------------------------ 
#define WINDOW_NAME1 "【原始圖窗口】"            //爲窗口標題定義的宏 
#define WINDOW_NAME2 "【輪廓圖】"                    //爲窗口標題定義的宏 


//-----------------------------------【全局變量聲明部分】--------------------------------------
//        描述:全局變量的聲明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage; 
Mat g_grayImage;
int g_nThresh = 80;
int g_nThresh_max = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector<vector<Point>> g_vContours;
vector<Vec4i> g_vHierarchy;


//-----------------------------------【全局函數聲明部分】--------------------------------------
//        描述:全局函數的聲明
//-----------------------------------------------------------------------------------------------
static void ShowHelpText( );
void on_ThreshChange(int, void* );


//-----------------------------------【main( )函數】--------------------------------------------
//        描述:控制檯應用程序的入口函數,我們的程序從這裏開始執行
//-----------------------------------------------------------------------------------------------
int main( int argc, char** argv )
{
    //【0】改變console字體顏色
    system("color 1F"); 

    // 加載源圖像
    g_srcImage = imread( "1.jpg", 1 );
    if(!g_srcImage.data ) { printf("讀取圖片錯誤,請確定目錄下是否有imread函數指定的圖片存在~! \n"); return false; } 

    // 轉成灰度並模糊化降噪
    cvtColor( g_srcImage, g_grayImage, COLOR_BGR2GRAY );
    blur( g_grayImage, g_grayImage, Size(3,3) );

    // 創建窗口
    namedWindow( WINDOW_NAME1, WINDOW_AUTOSIZE );
    imshow( WINDOW_NAME1, g_srcImage );

    //創建滾動條並初始化
    createTrackbar( "canny閾值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange );
    on_ThreshChange( 0, 0 );

    waitKey(0);
    return(0);
}

//-----------------------------------【on_ThreshChange( )函數】------------------------------  
//      描述:回調函數
//----------------------------------------------------------------------------------------------  
void on_ThreshChange(int, void* )
{

    // 用Canny算子檢測邊緣
    Canny( g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh*2, 3 );

    // 尋找輪廓
    findContours( g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );

    // 繪出輪廓
    Mat drawing = Mat::zeros( g_cannyMat_output.size(), CV_8UC3 );
    for( int i = 0; i< g_vContours.size(); i++ )
    {
        //Scalar color = Scalar( g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255) );//任意值
        Scalar color = Scalar(255, 182, 193);
        drawContours( drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point() );
    }

    vector<Point> tempPoint;     // 點集
    // 將所有點集存儲到tempPoint
    for (int k = 0; k < g_vContours.size(); k++)
    {
        for (int m = 0; m < g_vContours[k].size(); m++)
        {
            tempPoint.push_back(g_vContours[k][m]);
        }
    }
    //對給定的 2D 點集,尋找最小面積的包圍矩形
    RotatedRect box = minAreaRect(Mat(tempPoint));
    Point2f vertex[4];
    box.points(vertex);

    //繪製出最小面積的包圍矩形
    for (int i = 0; i < 4; i++)
    {
        line(drawing, vertex[i], vertex[(i + 1) % 4], Scalar(100, 200, 211), 2, LINE_AA);
    }

    imshow(WINDOW_NAME2, drawing);
}

最後的效果

Image 1.png

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