• 《学习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("请输入标签内容:
    ");
    				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]='';											//让cvPutText只打出之前的字符,不打印之后的空字符
    					c=getchar();															//接收最后的换行符
    					cvGetTextSize(current_label->text,&font,&current_label->text_size,NULL);
    					current_label->next=head;		head=current_label;						//插入到标签链表中
    					printf("创建了一个标签,内容为:%s
    ",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]='';     
    					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
    ",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;
    }
    

      

  • 相关阅读:
    QT学习——dialog、widget、mainwindow的区别和选择
    剑指offer——二叉树的深度
    位运算实现加减乘除四则运算
    剑指offer——求两个整数和
    C++常用设计模式
    从编程实现角度学习 Faster R-CNN(附极简实现)
    剑指offer——最小的k个数
    剑指offer——对称二叉树
    java 定时器
    rocketmq consumer接收到的MessageExt中各个字段的说明
  • 原文地址:https://www.cnblogs.com/luckyboylch/p/4906818.html
Copyright © 2020-2023  润新知