开发环境:vs2010+opencv2.2.0
源代码如下所示:
#ifdef _CH_
#pragma package <opencv>
#endif
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
IplImage* inpaint_mask = 0;
IplImage* img0 = 0,*img = 0,*inpainted = 0;
CvPoint prev_pt = {-1,-1};
void on_mouse(int event,int x,int y,int flags,void * zhang)
{
if(!img)
return;
if(event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))
prev_pt = cvPoint(-1,-1);
else if(event == CV_EVENT_LBUTTONDOWN)
prev_pt = cvPoint(x,y);
else if(event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
{
CvPoint pt = cvPoint(x,y);
if(prev_pt.x < 0)
prev_pt = pt;
cvLine(inpaint_mask,prev_pt,pt,cvScalarAll(255),5,8,0);
cvLine(img,prev_pt,pt,cvScalarAll(255),5,8,0);
prev_pt = pt;
cvShowImage("image",img);
}
}
int main(int argc,char **argv)
{
char *filename = argc >= 2 ? argv[1] : (char *)"fruits.jpg";
if((img0 = cvLoadImage(filename,-1)) == 0)
return 0;
printf("Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\ti or ENTER - run inpainting algorithm\n"
"\t\t(before running it,paint something on the image)\n");
cvNamedWindow("image",1);
img = cvCloneImage(img0);
inpainted = cvCloneImage(img0);
inpaint_mask = cvCreateImage(cvGetSize(img),8,1);
cvZero(inpaint_mask);
cvZero(inpainted);
cvShowImage("image",img);
cvShowImage("watershed transform",inpainted);
cvSetMouseCallback("image",on_mouse,0);
for(;;)
{
int c = cvWaitKey(0);
if((char)c == 27)
break;
if((char)c == 'r')
{
cvZero(inpaint_mask);
cvCopy(img0,img,0);
cvShowImage("image",img);
}
if((char)c == 'i' || (char)c == '\n')
{
cvNamedWindow("inpainted image",1);
cvInpaint(img,inpaint_mask,inpainted,3,CV_INPAINT_TELEA);
cvShowImage("inpainted image",inpainted);
}
}
return 1;
}
运行结果图如下所示:
重要函数解析:
CvPoint:是opencv的基本类型之一,表示一个坐标为整数的二维点,是一个包含interger类型成员x和y的简单结构体。其原型如下所示:
typedef struct CvPoint
{
int x; /* X坐标, 通常以0为基点 */
int y; /* y坐标, 通常以0为基点 */
}
CvPoint;
cvLine:opencv绘图函数 功能:绘制连接两点的线段
函数原型:void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
参数解析:img 图像。pt1 线段的第一个端点。pt2 线段的第二个端点。color 线段的颜色。thickness 线段的粗细程度。line_type 线段的类型。8 (or 0) - 8-connected line(8邻接)连接 线。4 - 4-connected line(4邻接)连接线。CV_AA - antialiased 线条。shift 坐标点的小数点位数。
函数cvLine 在图像中的点1和点2之间画一条线段。线段被图像或感兴趣的矩形(ROI rectangle)所裁剪。对于具有整数坐标的non-antialiasing 线条,使用8-连接或者4-连接Bresenham 算法。画粗线条时结尾是圆形的。画 antialiased 线条使用高斯滤波。要指定线段颜色,用户可以使用使用宏CV_RGB( r, g, b )。
而且指定线条颜色的时候用到的宏CV_RGB(r,g,b)定义为#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r), 0 ),由此可见,实际上起作用的颜色是看cvScalar中的b,g,r顺序,线段颜色就不言而喻了。
cvSetMouseCallback:原型为
void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param=NULL );
参数解析:
window_name: 窗口的名字。
on_mouse: 指定窗口里每次鼠标事件发生的时候,被调用的函数指针。
cvInpaint:功能为修复图像。