本章内容
* 對象提取
* 流程:
* 1.轉換成灰階圖像,并且二值化
* 2. 通過膨脹消除洞洞
* 3. 二值圖取非運算,将對象的值設定為255
* 4. 計算對象二值圖的距離
* 5. 搜尋輪廓,繪制對象
步驟一:灰階化,自适應二值化,膨脹操作,并取反
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL5czM1ADM1MTM0IzNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
輸出結果:
步驟二:計算二值圖距離,距離圖歸一化,距離圖二值化
輸出結果
步驟三:距離圖膨脹,輪廓搜尋,标記對象
輸出結果
源碼
#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;
}