#include "cv.h"
#include "highgui.h"
#include<stack>
using namespace cv;
using namespace std;
#define PI 3.1415926
#define RADIAN(angle) ((angle)*PI/180.0)
int direct[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
//轮廓提取
Mat Outline(Mat& mat)
{
int M=mat.rows;
int N=mat.cols;
Mat ret(M,N,CV_8U);
for(int i=1;i<M-1;i++)
{
for(int j=1;j<N-1;j++)
{
mat.at<uchar>(i,j)=(mat.at<uchar>(i,j)<128?0:255);
if(mat.at<uchar>(i,j)==0)
{
ret.at<uchar>(i,j)=0;
//查找八个相邻点
int num=0;
for(int k=-1;k<=1;k++)
for(int s=-1;s<=1;s++)
{
mat.at<uchar>(i+k,j+s)=(mat.at<uchar>(i+k,j+s)<128?0:255);
num+=mat.at<uchar>(i+k,j+s);
}
if(num==0)
ret.at<uchar>(i,j)=255;
}
else
ret.at<uchar>(i,j)=255;
}
}
return ret;
}
//种子填充
void SeedFill(Mat& mat,Point seedPoint)
{
int M=mat.rows;
int N=mat.cols;
stack<Point> st;
Point curPt,neighborPt;
st.push(seedPoint);
while(!st.empty())
{
curPt=st.top();
st.pop();
mat.at<uchar>(curPt.x,curPt.y)=0;
if(curPt.x>0) //上邻点
{
neighborPt.x=curPt.x-1;
neighborPt.y=curPt.y;
if(mat.at<uchar>(neighborPt.x,neighborPt.y)>128)
st.push(neighborPt);
}
if(curPt.y>0) //左邻点
{
neighborPt.x=curPt.x;
neighborPt.y=curPt.y-1;
if(mat.at<uchar>(neighborPt.x,neighborPt.y)>128)
st.push(neighborPt);
}
if(curPt.x<M-1)//下邻点
{
neighborPt.x=curPt.x+1;
neighborPt.y=curPt.y;
if(mat.at<uchar>(neighborPt.x,neighborPt.y)>128)
st.push(neighborPt);
}
if(curPt.y<N-1) //右邻点
{
neighborPt.x=curPt.x;
neighborPt.y=curPt.y+1;
if(mat.at<uchar>(neighborPt.x,neighborPt.y)>128)
st.push(neighborPt);
}
}
}
//轮廓跟踪
Mat Contour(Mat& mat)
{
int M=mat.rows;
int N=mat.cols;
Mat ret(M,N,CV_8U,Scalar(255));
//寻找最左上的边界点
bool found=false;
int i,j;
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
if(mat.at<uchar>(i,j)<128)
{
found=true;
break;
}
}
if(found)
break;
}
if(found)
{
Point startPt,curPt;
startPt.x=i;
startPt.y=j;
ret.at<uchar>(i,j)=0;
//寻找相邻中的黑点
for(int k=0;k<4;k++)
{
curPt.x=startPt.x+direct[k][0];
curPt.y=startPt.y+direct[k][1];
if(mat.at<uchar>(curPt.x,curPt.y)<128)
break;
}
while(!(startPt.x==curPt.x&&startPt.y==curPt.y))
{
ret.at<uchar>(curPt.x,curPt.y)=0;
for(int k=0;k<8;k++)
{
int x=curPt.x+direct[k][0];
int y=curPt.y+direct[k][1];
if((mat.at<uchar>(x,y)<128&&ret.at<uchar>(x,y)>128)||
(x==startPt.x&&y==startPt.y))
{
//判断是否是边界点
if(!((x-1>=0&&mat.at<uchar>(x-1,y)<128)&&
(y-1>=0&&mat.at<uchar>(x,y-1)<128)&&
(x+1<M&&mat.at<uchar>(x+1,y)<128)&&
(y+1<N&&mat.at<uchar>(x,y+1)<128)))
{
curPt.x=x;
curPt.y=y;
break;
}
}
}
}
}
return ret;
}
int main()
{
//读取图像
Mat image;
image=imread("outline.jpg",CV_LOAD_IMAGE_GRAYSCALE);
int M=image.rows;
int N=image.cols;
Mat newImage=Contour(image);
//SeedFill(image, Point(70,70));
cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
imshow("test",newImage);
waitKey(0);
return 0;
}
图像处理之轮廓处理
最新推荐文章于 2020-11-02 14:49:12 发布