《学习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;
}

  

posted @ 2015-10-24 14:42  Coding练习生  阅读(243)  评论(0编辑  收藏  举报