本章内容
* 对象提取
* 流程:
* 1.转换成灰度图像,并且二值化
* 2. 通过膨胀消除洞洞
* 3. 二值图取非运算,将对象的值设置为255
* 4. 计算对象二值图的距离
* 5. 搜索轮廓,绘制对象
步骤一:灰度化,自适应二值化,膨胀操作,并取反
输出结果:
步骤二:计算二值图距离,距离图归一化,距离图二值化
输出结果
步骤三:距离图膨胀,轮廓搜索,标记对象
输出结果
源码
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
int main(int argc, char* argv[]){
/*本章内容
* 对象提取
* 流程:
* 1.转换成灰度图像,并且二值化
* 2. 通过膨胀消除洞洞
* 3. 二值图取非运算,将对象的值设置为255
* 4. 计算对象二值图的距离
* 5. 搜索轮廓,绘制对象*/
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;
}