《学习OpenCV》 第四章 习题六

时间:2023-03-09 01:41:05
《学习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,&current_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,&current_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;
}