天天看點

opencv 對象提取與标記

本章内容

     * 對象提取

     * 流程:

     * 1.轉換成灰階圖像,并且二值化

     * 2. 通過膨脹消除洞洞

     * 3. 二值圖取非運算,将對象的值設定為255

     * 4. 計算對象二值圖的距離

     * 5. 搜尋輪廓,繪制對象

步驟一:灰階化,自适應二值化,膨脹操作,并取反

opencv 對象提取與标記

輸出結果:

opencv 對象提取與标記

步驟二:計算二值圖距離,距離圖歸一化,距離圖二值化

opencv 對象提取與标記

輸出結果

opencv 對象提取與标記

步驟三:距離圖膨脹,輪廓搜尋,标記對象

opencv 對象提取與标記

輸出結果

opencv 對象提取與标記

源碼

#include <opencv2/opencv.hpp>

#include <iostream>

#include <math.h>

int main(int argc, char* argv[]){

    cv::String fileName = "/home/wang/dev/Image/baogu.png";

    cv::Mat src = cv::imread("/home/wang/dev/Image/baogu.png");

    if(src.data == NULL){

        std::cout << " 圖像檔案讀入失敗" << std::endl;

        return -1;

    }

    cv::imshow("src",src);

    cv::Mat gray;

    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    cv::Mat grayBinary;

    cv::threshold(gray,grayBinary,0,255,cv::THRESH_BINARY|cv::THRESH_OTSU);

    cv::imshow("gray binary",grayBinary);

    // 膨脹運算,腐蝕邊界

    cv::dilate(grayBinary,grayBinary,cv::Mat::ones(3,3,CV_8U),cv::Point(-1,-1),3);

    cv::imshow("gray binaty dilate",grayBinary);

    // 二值圖取非

    cv::bitwise_not(grayBinary,grayBinary);

    cv::imshow("bitwise_not", grayBinary);

    // 計算距離

    cv::Mat dist;

    cv::distanceTransform(grayBinary,dist,cv::DIST_L2,3);

    cv::normalize(dist,dist,0,1,cv::NORM_MINMAX);

    cv::imshow("dist",dist);

    // 距離二值化,分割粘貼在一起的對象

    cv::Mat dist8u;

    dist.convertTo(dist8u,CV_8U);

    cv::threshold(dist8u,dist8u,0,255,cv::THRESH_BINARY|cv::THRESH_OTSU);

    cv::imshow("dist Binary",dist8u);

    cv::dilate(dist8u,dist8u,cv::Mat::ones(3,3,CV_8U),cv::Point(-1,-1),3);

    cv::imshow("dist Binary dilate",dist8u);

    // 輪廓搜尋

    std::vector<std::vector<cv::Point>> contours;

    cv::findContours(dist8u,contours,0,cv::CHAIN_APPROX_SIMPLE);

    // 繪制對象輪廓

    cv::Mat Markers(src.size(),CV_8UC3);

    cv::RNG rng(123456);

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

        cv::Scalar color = cv::Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));

        cv::drawContours(src,contours,i,color,4);

    }

    cv::imshow("Markers", src);

    cv::waitKey(0);

    return 1;

}

繼續閱讀