《学习OpenCV》 第四章 习题六
实现的是一个图像标签编辑器,其间遇到了些问题还未解决或者可能解决方法上不是最优,若你有更好的思路可以提供给我,大恩不言谢啦!!☆⌒(*^-゜)v。
#include "stdafx.h" #include "cv.h" #include "highgui.h" #include "stdio.h" #define LEN sizeof(struct Label) void callback(int event, int x, int y, int flags, void* param); void* isCreated(struct Label* head,CvPoint* position); //判断鼠标当前所在位置是否已经创建了标签,若已创建了则返回该标签的指针 struct Label{ //标签结构体 char text[50]; CvPoint point; CvSize text_size; //标签文字所占区域 struct Label* next; }*head,*current_label; //标签链表的头结点,插入新结点采用头入式 bool flag=false; //判断鼠标所在位置是否已创建了标签,false表示能创建新标签,true表示已创建只能够编辑原标签 bool isDown=false; //判断是否单击了鼠标 CvPoint position; //鼠标当前位置 CvFont font; /*******************这是一个简单的图像标签编辑器***********************/ /* 还有些细节或不足有待完善 */ /* 1、不能够光标式地逐字编辑已有的标签 */ /* 2、对已创建的标签无法实现准确定位和完全擦除 */ /* 3、当快速或大量地进行标签的编辑和创建会出现性能问题 */ /* 4、当鼠标定位到一个已存在的标签时应当高亮等提示 */ /* 5、编辑已存在标签时无法实现换行输出 */ /**********************************************************************/ /*********************************使用说明*****************************/ /* 1、单击鼠标确定要创建或编辑的标签位置 */ /* 2、在命令行窗口下输入标签的内容(非中文,单行) */ /* 3、输入内容后最后以#字符结束并回车 */ /**********************************************************************/ int main() { IplImage* img=cvCreateImage(cvSize(500,500),8,3); cvZero(img); cvNamedWindow("标签编辑器"); cvSetMouseCallback("标签编辑器",callback,img); cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5); //设置统一的字体 char keycode=0,c; int i; while(1) { cvShowImage("标签编辑器",img); keycode=cvWaitKey(30); i=0; switch(keycode) { case 13: //按Enter键进入编辑状态 { if(isDown) { printf("请输入标签内容:\n"); if(flag==false) //该位置还未创建标签 { current_label=(struct Label*)malloc(LEN); current_label->point=cvPoint(position.x,position.y); while((c=getchar())!=35 && i<50) //若最后输入'#'则退出编辑 { current_label->text[i++]=c; } current_label->text[i]='\0'; //让cvPutText只打出\0之前的字符,不打印之后的空字符 c=getchar(); //接收最后的换行符 cvGetTextSize(current_label->text,&font,¤t_label->text_size,NULL); current_label->next=head; head=current_label; //插入到标签链表中 printf("创建了一个标签,内容为:%s\n",current_label->text); } else { cvSetImageROI( img, cvRect(current_label->point.x-2,current_label->point.y-current_label->text_size.height-2,current_label->text_size.width+8,current_label->text_size.height+8) ); cvZero(img); cvResetImageROI(img); memset(current_label->text,0,sizeof(current_label->text)); //将text全部置空 while((c=getchar())!=35 && i<50) { current_label->text[i++]=c; } current_label->text[i]='\0'; c=getchar(); //接收最后的Enter键 cvGetTextSize(current_label->text,&font,¤t_label->text_size,NULL); } cvPutText(img,current_label->text,current_label->point,&font,cvScalar(255,255,255)); flag=false; isDown=false; } } break; case 27: //按Esc直接关闭当前窗口 return 0; default: break; } } cvDestroyWindow("标签编辑器"); cvReleaseImage(&img); return 0; } void callback(int event, int x, int y, int flags, void* param) { IplImage* img=(IplImage*)param; switch(event) { case CV_EVENT_LBUTTONDOWN: { isDown=true; position.x=x; position.y=y; current_label=(Label*)isCreated(head,&position); if(current_label) { flag=true; printf("当前标签内容为:%s\n",current_label->text); } else flag=false; } break; } } void* isCreated(struct Label* head,CvPoint* position) { struct Label *p=head,*dst=NULL; while(p!=NULL) { if(position->x>=(p->point.x-4) && position->x<=(p->point.x+p->text_size.width+4) && position->y>=(p->point.y-p->text_size.height-4) && position->y<=(p->point.y+6)) { dst=p; return (void*)dst; } p=p->next; } return NULL; }