chap 4. 2 在图上显示鼠标点击处的B G R分量值
本程序的简化为,鼠标点击之处的 b g r 分量在 cmd窗口显示
图片上显示 固定语句 "hello"
#include<opencv2/opencv.hpp>
#include<iostream>
// 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<<b<<" "<<g<<" "<<r<<endl;
CvFont font=cvFont(5,1);
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1,1,0,1,8);
cvPutText(img,"hello",point,&font,cvScalar(0,0,255));
cvShowImage("one",img);
key_down=false;
if(cvWaitKey(50)>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 .....之类的。
如果你有更简洁的代码或思路,欢迎共享与讨论。