OpenCV 4.2习题解答

chap 4. 2  在图上显示鼠标点击处的B G R分量值

本程序的简化为,鼠标点击之处的 b  g  r 分量在 cmd窗口显示

图片上显示 固定语句 "hello"

#include
#include
// chap 4.2 

IplImage* img=NULL;
bool key_down=false;
CvPoint point=cvPoint(0,0);
void mymouse_callback(int event, int x, int y, int flags, void* param)
{
	point.x=x;
	point.y=y;
	switch(event)
	{
	case CV_EVENT_LBUTTONDOWN:
		{
			key_down=true;
		}
		break;
	case CV_EVENT_LBUTTONUP:
		{
			cvZero(img); 
			img=cvLoadImage("d:\\lxlx\\one.jpg");// refresh img
		}
		break;
	default:
		{
			
		}
		break;
	}
}
void main()
{
	using namespace std;
	cvNamedWindow("one");
	IplImage* src=cvLoadImage("D:\\lxlx\\one.jpg");	
	img=cvCreateImage(cvGetSize(src),8,3);
	cvCopy(src,img);
	while(1)
	{
		cvSetMouseCallback("one",mymouse_callback,(void*)img);
		if(key_down)
		{
			uchar* ptr=(uchar*)(img->imageData+point.y*img->widthStep);
			int b=ptr[3*point.x+0];
			int g=ptr[3*point.x+1];
			int r=ptr[3*point.x+2];
			cout<0)
				break;			
		}
		else
		{
			cvShowImage("one",img);
			if(cvWaitKey(50)>0)
				break;	
		}
			
	}
	cvReleaseImage(&src);
	cvReleaseImage(&img);
	cvDestroyWindow("one");
}

1,由于响应鼠标事件需要回调函数,所以在回调函数 mymouse_callback 中,判定 鼠标左键是否按下。

如果按下,则全局变量 key_down = true ; 否则, key_down = false;

2,将 img 定义为全局变量,可以在 回调函数中的 void* param直接使用 img 而非 param , 实际上没什么区别。

3, 左键抬起,将 img  清零,并重新加载原始的图像 one.jpg 。

 这样做的目的是单击后,显示BGR分量和“hello”,抬起后恢复图片;下次单击,则是原始的图片。

如果没有该部分,则每单击一次,图片上多出一处“hello” 语句。 

4,src 的作用也是相似的。

如果将  src = cvLoadImage("D:\\lxlx\\one.jpg") ; 

直接改成 img=cvLoadImage("D:\\lxlx\\one.jpg");

那么每单击一次,多一处 “hello” 语句。

5,全局变量 CvPoint point 是为了标记单击坐标。

6,key_down 内部前几行代码是取该坐标点处的 B  G R 分量。

之前我写的代码和这个有所不同,才用的是 cvPtr2D( ) 。

由于取分量的BGR值时,相应的偏移量没有计算正确,导致单击若干点后,会出现错误。

错误提示: 。。。。out of range .....之类的。

如果你有更简洁的代码或思路,欢迎共享与讨论。

你可能感兴趣的:(opencv,opencv,取像素点)