利用OpenCV绘制可变直线

转载自:http://blog.csdn.net/quarryman/article/details/6450788

      变直线就是绘制后的直线可以修改起始点和终止点(当然包括直线的长度)。绘制后的直线两端有矩形方块,在矩形方块内拖动光标就可以修改直线了。

#include <cv.h>
#include <highgui.h>
#pragma comment( lib, "cv.lib" )
#pragma comment( lib, "cxcore.lib" )
#pragma comment( lib, "highgui.lib" )
IplImage* org=0;
IplImage* tmp=0;
IplImage* img=0;
void on_mouse( int event, int x, int y, int flags, void* ustc)
{
	static CvPoint pre={-1,-1};
	static CvPoint cur={-1,-1};
	static int complete=0;
	static int inbrect=0;
	static int inerect=0;
	if( event == CV_EVENT_LBUTTONDOWN && !complete)
	{		
		if((short)x<5)
		{
			x=5;
		}
		else if((short)x>org->width-5)
		{
			x=org->width-5;
		}
		if((short)y<5)
		{
			y=5;
		}
		else if((short)y>org->height-5)
		{
			y=org->height-5;
		}
		pre=cvPoint(x,y);
		cur=cvPoint(x,y);
		cvRectangle(tmp,cvPoint(x-5,y-5),cvPoint(x+5,y+5),CV_RGB(0,255,0));
		cvCopy(tmp,img);
		cvShowImage("image",tmp);	
	}
	else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) && !complete)
	{
		cvCopy(img,tmp);
		if((short)x<5)
		{
			x=5;
		}
		else if((short)x>org->width-5)
		{
			x=org->width-5;
		}
		if((short)y<5)
		{
			y=5;
		}
		else if((short)y>org->height-5)
		{
			y=org->height-5;
		}
		cur = cvPoint(x,y);
		cvLine( tmp, pre, cur, cvScalar(0,255,0,0), 1, CV_AA, 0 );
		cvRectangle(tmp,cvPoint(x-5,y-5),cvPoint(x+5,y+5),CV_RGB(0,255,0));
		cvShowImage( "image", tmp );
	}
	else if(event == CV_EVENT_LBUTTONUP  && !complete)
	{
		complete=1;
	}
	else if((event == CV_EVENT_LBUTTONDOWN) && complete)
	{
		if(x>=pre.x-5 && x<=pre.x+5 && y>=pre.y-5 && y<=pre.y+5)
		{
			inbrect=1;
		}
		else 
		{
			inbrect=0;
		}
		if(x>=cur.x-5 && x<=cur.x+5 && y>=cur.y-5 && y<=cur.y+5)
		{
			inerect=1;
		}
		else
		{
			inerect=0;
		}
	}
	else if( (event == CV_EVENT_MOUSEMOVE) && (flags & CV_EVENT_FLAG_LBUTTON) && complete && (inbrect || inerect))
	{
		cvCopy(org,tmp);	
		if(inbrect)
		{			
			if(cur.x<5)
			{
				cur.x=5;
			}
			else if(cur.x>org->width-5)
			{
				cur.x=org->width-5;
			}
			if(cur.y<5 && cur.y>=0)
			{
				cur.y=5;
			}
			else if(cur.y>org->height-5)
			{
				cur.y=org->height-5;
			}
			cvRectangle(tmp,cvPoint(cur.x-5,cur.y-5),cvPoint(cur.x+5,cur.y+5),CV_RGB(0,255,0));
			if((short)x<5)
			{
				x=5;
			}
			else if((short)x>org->width-5)
			{
				x=org->width-5;
			}
			if((short)y<5)
			{
				y=5;
			}
			else if((short)y>org->height-5)
			{
				y=org->height-5;
			}
			cvRectangle(tmp,cvPoint(x-5,y-5),cvPoint(x+5,y+5),CV_RGB(0,255,0));
			cvLine( tmp, cvPoint(x,y),cur, cvScalar(0,255,0,0), 1, CV_AA, 0 );
			pre=cvPoint(x,y);
		}
		else if(inerect)
		{		
			if(pre.x<5)
			{
				pre.x=5;
			}
			if(pre.x>org->width-5)
			{
				pre.x=org->width-5;
			}
			if(pre.y<5)
			{
				pre.y=5;
			}
			if(pre.y>org->height-5)
			{
				pre.y=org->height-5;
			}
			cvRectangle(tmp,cvPoint(pre.x-5,pre.y-5),cvPoint(pre.x+5,pre.y+5),CV_RGB(0,255,0));
			if((short)x<5)
			{
				x=5;
			}
			else if((short)x>org->width-5)
			{
				x=org->width-5;
			}
			if((short)y<5)
			{
				y=5;
			}
			else if((short)y>org->height-5)
			{
				y=org->height-5;
			}
			cvRectangle(tmp,cvPoint(x-5,y-5),cvPoint(x+5,y+5),CV_RGB(0,255,0));
			cvLine( tmp, pre, cvPoint(x,y), cvScalar(0,255,0,0), 1, CV_AA, 0 );
			cur=cvPoint(x,y);
		}
		
		cvShowImage( "image", tmp );
	}
}
int main()
{
	org=cvLoadImage("lena.jpg",1);
	tmp=cvCloneImage(org);
	img=cvCloneImage(org);
	cvNamedWindow("image", 1 );
	cvShowImage("image",org);
	cvSetMouseCallback( "image", on_mouse, 0 );
	cvWaitKey(0);
	cvDestroyWindow("image");
	cvReleaseImage(&org);
	cvReleaseImage(&tmp);
	cvReleaseImage(&img);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
利用OpenCV绘制多边形,通常需要按照以下步骤进行: ### 准备工作 首先,确保已经安装了 OpenCV 库。如果没有安装,可以通过 pip 安装 OpenCV: ```bash pip install opencv-python ``` ### 导入库 在 Python 脚本中导入所需的库: ```python import cv2 import numpy as np ``` ### 加载图像 加载你要绘制多边形的图像。这里我们使用的是 `.jpg` 格式的图片: ```python image = cv2.imread('path_to_your_image.jpg') ``` ### 获取鼠标点击事件 我们需要捕获鼠标点击事件来收集多边形的顶点坐标。我们将创建一个回调函数来记录每次鼠标点击的位置。 ```python points = [] # 存储点击点的坐标 def draw_polygon(event, x, y, flags, params): if event == cv2.EVENT_LBUTTONDOWN: points.append([x, y]) return # 将回调函数绑定到图像窗口 cv2.setMouseCallback('image', draw_polygon) ``` ### 绘制多边形 在用户完成点击并按特定按键(比如 "Esc" 或 "Enter" 等)退出绘制模式后,我们可以根据收集到的坐标绘制多边形: ```python while True: # 显示图像,同时更新坐标点列表 cv2.imshow('image', image) # 检查键盘输入是否为 Esc 键退出 k = cv2.waitKey(1) & 0xFF if k == 27: # 27 is the ASCII code of the Esc key break # 每次用户点击后,添加新的坐标至列表 if len(points) >= 4: # 使用numpy将列表转换为数组,并计算闭合多边形的轮廓边界 points_array = np.array(points, dtype=np.int32) polygon = points_array.reshape((-1, 1, 2)) # 适配OpenCV的多边形绘制格式 # 绘制多边形 cv2.polylines(image, [polygon], True, (0, 255, 0), 2) # 清空列表准备下次绘制 points.clear() # 关闭所有窗口 cv2.destroyAllWindows() ``` ### 相关问题: 1. **如何自定义绘制的颜色和线宽?** 可以在 `cv2.polylines()` 的参数中直接设置颜色和线宽,例如 `(color=(0, 255, 0), thickness=2)`。 2. **如何绘制填充的多边形而不是边缘?** 对于封闭的多边形,可以通过 `cv2.fillPoly()` 函数填充满颜色,首先需要创建一个与原始图像等大的白色背景图像作为 mask,然后指定要填充的多边形区域。 3. **如何优化性能以处理大尺寸图像或多边形?** 对于大型图像或频繁的多边形绘制操作,考虑使用更高效的绘图算法或硬件加速选项,如 OpenCV 的 GPU 支持功能。同时,合理管理内存使用,避免不必要的数据复制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值