Opencv2 computer vision application programming cookbook<四>

来源:互联网 发布:车来了软件 编辑:程序博客网 时间:2024/05/17 22:41

第五章介绍形态学

图像的腐蚀,膨胀,开,闭,利用形态学滤波图像进行边缘及角点检测,最全是分水岭算法,GrabCut算法提取前景物体

#include "stdafx.h"
#include<iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;


class MorphoFeatures
{
private:
//用于生成二值图像的阈值
int threshold;
//角点检测中用到的结构元素
Mat cross;
Mat diamond;
Mat square;
Mat x;


void applyThreshold(Mat & result)
{
if(threshold>0)
cv::threshold(result,result,threshold,255,THRESH_BINARY);
}
public:
MorphoFeatures():threshold(-1),cross(5,5,CV_8U,Scalar(0)),
diamond(5,5,CV_8U,Scalar(1)),square(5,5,CV_8U,Scalar(1)),
x(5,5,CV_8U,Scalar(0))
{
//创建十字形元素
for(int i =0;i<5;i++)
{
cross.at<uchar>(2,i)=1;
cross.at<uchar>(i,2)=1;
}


//创建菱形元素
diamond.at<uchar>(0,0)=0;
diamond.at<uchar>(0,1)=0;
diamond.at<uchar>(1,0)=0;
diamond.at<uchar>(4,4)=0;
diamond.at<uchar>(3,4)=0;
diamond.at<uchar>(4,3)=0;
diamond.at<uchar>(4,0)=0;
diamond.at<uchar>(4,1)=0;
diamond.at<uchar>(3,0)=0;
diamond.at<uchar>(0,4)=0;
diamond.at<uchar>(0,3)=0;
diamond.at<uchar>(1,4)=0;


//创建X形元素
for(int i=0;i<5;i++)
{
x.at<uchar>(i,i)=1;
x.at<uchar>(4-i,i)=1;
}


}
void SetThreshold(int n)
{
threshold=n;
}


Mat getEdges(const Mat &image)
{
//得到梯度图
Mat result;
morphologyEx(image,result,MORPH_GRADIENT,Mat());
//阈值得到二值图像
applyThreshold(result);
return result;
}
Mat getCorners(const Mat & image)
{
Mat result;
//十字形膨胀
dilate(image,result,cross);
//菱形腐蚀
erode(result,result,diamond);
Mat result2;
//X形膨胀
dilate(image,result2,x);
//方形腐蚀
erode(result2,result2,square);
//通过对两张图像做差值得到角点图像
absdiff(result2,result,result);
//阈值化得到二值图像
applyThreshold(result);
return result;
}


void drawOnImage(const Mat & binary,Mat & image)
{
//三通道图像
//Mat_<Vec3b>::const_iterator it=binary.begin<Vec3b>();
//Mat_<Vec3b>::const_iterator itend=binary.end<Vec3b>();
////遍历每个像素
//int step=image.step/3;
//for(int i=0;it!=itend;++it,++i)
//{
// if((*it)[0]++!=0)
// {
// circle(image,Point(i%step,i/step),5,Scalar(0,0,255));
// }
//}


//单通道图像
 cv::Mat_<uchar>::const_iterator it= binary.begin<uchar>();
 cv::Mat_<uchar>::const_iterator itend= binary.end<uchar>();
 // for each pixel
 for (int i=0; it!= itend; ++it,++i)
 {
 if (*it!=0)
 circle(image,cv::Point(i%image.step,i/image.step),5,cv::Scalar(0,0,255));
 }
}


};


class WatershedSegment
{
private:
Mat markers;
public:
void setMarkers(const Mat & markerImage)
{
//转换为整数图像
markerImage.convertTo(markers,CV_32S);
}


Mat process(const Mat & image)
{
cv::watershed(image,markers);
return markers;
}
Mat getSegmentation()
{
Mat temp;
markers.convertTo(temp,CV_8U);
return temp;
}
Mat getWatersheds()
{
Mat temp;
markers.convertTo(temp,CV_8U,255,255);
return temp;
}
};


int _tmain(int argc, _TCHAR* argv[])
{




////图像角点--通过形态学得到
//Mat image=imread("test.bmp",0);
//imshow("test",image);
////腐蚀图像
//Mat eroded;
//erode(image,eroded,Mat(),Point(-1,-1),3);
////imshow("eroded image",eroded);
////膨胀图像
//Mat dilated;
//dilate(image,dilated,Mat(),Point(-1,-1),3);
////imshow("dilated image",dilated);
//
////使用结构元素,默认为3X3方形结构元素
//Mat element7(7,7,CV_8U,Scalar(1));
//Mat eroded1;
//erode(image,eroded1,element7);
////imshow("eroded1 image",eroded1);


//Mat element5(5,5,CV_8U,Scalar(1));
//Mat closed;
//morphologyEx(image,closed,MORPH_CLOSE,element5);
////morphologyEx(image,closed,MORPH_OPEN,element5);
////imshow("closed image",closed);

//图像通道的分离与合并
//vector<Mat> splitImage;
//split(image,splitImage);
//Mat blue;
//Mat green;
//Mat red;
//blue=splitImage.at(0);
//green=splitImage.at(1);
//red=splitImage.at(2);
//merge(splitImage,image);


////获取角点
//MorphoFeatures morpho;
//morpho.SetThreshold(40);
////获取边缘
//Mat edges;
//edges=morpho.getEdges(image);
////imshow("edges",edges);
//morpho.SetThreshold(40);
//Mat corners;
//corners=morpho.getCorners(image);
//morpho.drawOnImage(corners,image);
//imshow("corners",corners);
//imshow("corners on image",image);
//////////




////watershed图像分割
//Mat image=imread("lena512.bmp");
//Mat binary=imread("lenabinary.bmp",0);
////移除噪点与微小物体
//Mat fg;
//erode(binary,fg,Mat(),Point(-1,-1),6);
////imshow("1",fg);
//Mat bg;
//dilate(binary,bg,Mat(),Point(-1,-1),6);
//threshold(bg,bg,1,128,THRESH_BINARY_INV);
////imshow("2",bg);


//////创建标记图像
//Mat markers(binary.size(),CV_8U,Scalar(0));
//markers=fg+bg;
////imshow("3",markers);


//WatershedSegment segment;
//segment.setMarkers(markers);
//segment.process(image);
//Mat segmentImage;
//segmentImage= segment.getWatersheds();
////segmentImage= segment.getSegmentation();
//imshow("4",segmentImage);


//GrabCut
Mat image=imread("lena512.bmp");


//定义前景物体的矩形
Rect rectangle(242,169,20,20);
//分割(四种可能的值)
Mat result;
Mat bgModel,fgModel;//模型(供内部使用)
//GrabCut分割
grabCut(image,//输入图像
result,//分割结果
rectangle,//包含前景物体的矩形
bgModel,//模型
fgModel,
1//迭代次数
,GC_INIT_WITH_RECT);//使用矩形进行初始化
//GC_BGD:确定属于前景的像素
//GC_FGD:确定属于背景的像素
//GC_PR_BGD:可能属于背景的像素
//GC_PR_FGD:可能属于前景的像素


compare(result,GC_PR_BGD,result,CMP_EQ);
Mat foreground(image.size(),CV_8UC3,Scalar(255,255,255));//指定区域
image.copyTo(foreground,result);
result=result &1;
imshow("result",foreground);


waitKey();
return 0;
}


0 0
原创粉丝点击