Python OpenCV实现鼠标画框效果


Posted in Python onAugust 19, 2020

使用Python+OpenCV实现鼠标画框的代码,供大家参考,具体内容如下

Python OpenCV实现鼠标画框效果

# -*-coding: utf-8 -*-
"""
 @Project: IntelligentManufacture
 @File : user_interaction.py
 @Author : panjq
 @E-mail : pan_jinquan@163.com
 @Date : 2019-02-21 15:03:18
"""
# -*- coding: utf-8 -*-
 
import cv2
from utils import image_processing
import numpy as np
global img
global point1, point2
global g_rect
 
def on_mouse(event, x, y, flags, param):
 global img, point1, point2,g_rect
 img2 = img.copy()
 if event == cv2.EVENT_LBUTTONDOWN: # 左键点击,则在原图打点
 print("1-EVENT_LBUTTONDOWN")
 point1 = (x, y)
 cv2.circle(img2, point1, 10, (0, 255, 0), 5)
 cv2.imshow('image', img2)
 
 elif event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_LBUTTON): # 按住左键拖曳,画框
 print("2-EVENT_FLAG_LBUTTON")
 cv2.rectangle(img2, point1, (x, y), (255, 0, 0), thickness=2)
 cv2.imshow('image', img2)
 
 elif event == cv2.EVENT_LBUTTONUP: # 左键释放,显示
 print("3-EVENT_LBUTTONUP")
 point2 = (x, y)
 cv2.rectangle(img2, point1, point2, (0, 0, 255), thickness=2)
 cv2.imshow('image', img2)
 if point1!=point2:
  min_x = min(point1[0], point2[0])
  min_y = min(point1[1], point2[1])
  width = abs(point1[0] - point2[0])
  height = abs(point1[1] - point2[1])
  g_rect=[min_x,min_y,width,height]
  cut_img = img[min_y:min_y + height, min_x:min_x + width]
  cv2.imshow('ROI', cut_img)
 
def get_image_roi(rgb_image):
 '''
 获得用户ROI区域的rect=[x,y,w,h]
 :param rgb_image:
 :return:
 '''
 bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
 global img
 img=bgr_image
 cv2.namedWindow('image')
 while True:
 cv2.setMouseCallback('image', on_mouse)
 # cv2.startWindowThread() # 加在这个位置
 cv2.imshow('image', img)
 key=cv2.waitKey(0)
 if key==13 or key==32:#按空格和回车键退出
  break
 cv2.destroyAllWindows()
 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 return g_rect
 
def select_user_roi(image_path):
 '''
 由于原图的分辨率较大,这里缩小后获取ROI,返回时需要重新scale对应原图
 :param image_path:
 :return:
 '''
 orig_image = image_processing.read_image(image_path)
 orig_shape = np.shape(orig_image)
 resize_image = image_processing.resize_image(orig_image, resize_height=800,resize_width=None)
 re_shape = np.shape(resize_image)
 g_rect=get_image_roi(resize_image)
 orgi_rect = image_processing.scale_rect(g_rect, re_shape,orig_shape)
 roi_image=image_processing.get_rect_image(orig_image,orgi_rect)
 image_processing.cv_show_image("RECT",roi_image)
 image_processing.show_image_rect("image",orig_image,orgi_rect)
 return orgi_rect
 
 
if __name__ == '__main__':
 # image_path="../dataset/images/IMG_0007.JPG"
 image_path="../dataset/test_images/lena.jpg"
 
 # rect=get_image_roi(image)
 rect=select_user_roi(image_path)
 print(rect)

其中image_processing.py文件如下:

# -*-coding: utf-8 -*-
"""
 @Project: IntelligentManufacture
 @File : image_processing.py
 @Author : panjq
 @E-mail : pan_jinquan@163.com
 @Date : 2019-02-14 15:34:50
"""
 
import os
import glob
import cv2
import numpy as np
import matplotlib.pyplot as plt
 
def show_image(title, image):
 '''
 调用matplotlib显示RGB图片
 :param title: 图像标题
 :param image: 图像的数据
 :return:
 '''
 # plt.figure("show_image")
 # print(image.dtype)
 plt.imshow(image)
 plt.axis('on') # 关掉坐标轴为 off
 plt.title(title) # 图像题目
 plt.show()
 
def cv_show_image(title, image):
 '''
 调用OpenCV显示RGB图片
 :param title: 图像标题
 :param image: 输入RGB图像
 :return:
 '''
 channels=image.shape[-1]
 if channels==3:
 image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # 将BGR转为RGB
 cv2.imshow(title,image)
 cv2.waitKey(0)
 
def read_image(filename, resize_height=None, resize_width=None, normalization=False):
 '''
 读取图片数据,默认返回的是uint8,[0,255]
 :param filename:
 :param resize_height:
 :param resize_width:
 :param normalization:是否归一化到[0.,1.0]
 :return: 返回的RGB图片数据
 '''
 
 bgr_image = cv2.imread(filename)
 # bgr_image = cv2.imread(filename,cv2.IMREAD_IGNORE_ORIENTATION|cv2.IMREAD_COLOR)
 if bgr_image is None:
 print("Warning:不存在:{}", filename)
 return None
 if len(bgr_image.shape) == 2: # 若是灰度图则转为三通道
 print("Warning:gray image", filename)
 bgr_image = cv2.cvtColor(bgr_image, cv2.COLOR_GRAY2BGR)
 
 rgb_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2RGB) # 将BGR转为RGB
 # show_image(filename,rgb_image)
 # rgb_image=Image.open(filename)
 rgb_image = resize_image(rgb_image,resize_height,resize_width)
 rgb_image = np.asanyarray(rgb_image)
 if normalization:
 # 不能写成:rgb_image=rgb_image/255
 rgb_image = rgb_image / 255.0
 # show_image("src resize image",image)
 return rgb_image
def resize_image(image,resize_height, resize_width):
 '''
 :param image:
 :param resize_height:
 :param resize_width:
 :return:
 '''
 image_shape=np.shape(image)
 height=image_shape[0]
 width=image_shape[1]
 if (resize_height is None) and (resize_width is None):#错误写法:resize_height and resize_width is None
 return image
 if resize_height is None:
 resize_height=int(height*resize_width/width)
 elif resize_width is None:
 resize_width=int(width*resize_height/height)
 image = cv2.resize(image, dsize=(resize_width, resize_height))
 return image
def scale_image(image,scale):
 '''
 :param image:
 :param scale: (scale_w,scale_h)
 :return:
 '''
 image = cv2.resize(image,dsize=None, fx=scale[0],fy=scale[1])
 return image
 
 
def get_rect_image(image,rect):
 '''
 :param image:
 :param rect: [x,y,w,h]
 :return:
 '''
 x, y, w, h=rect
 cut_img = image[y:(y+ h),x:(x+w)]
 return cut_img
def scale_rect(orig_rect,orig_shape,dest_shape):
 '''
 对图像进行缩放时,对应的rectangle也要进行缩放
 :param orig_rect: 原始图像的rect=[x,y,w,h]
 :param orig_shape: 原始图像的维度shape=[h,w]
 :param dest_shape: 缩放后图像的维度shape=[h,w]
 :return: 经过缩放后的rectangle
 '''
 new_x=int(orig_rect[0]*dest_shape[1]/orig_shape[1])
 new_y=int(orig_rect[1]*dest_shape[0]/orig_shape[0])
 new_w=int(orig_rect[2]*dest_shape[1]/orig_shape[1])
 new_h=int(orig_rect[3]*dest_shape[0]/orig_shape[0])
 dest_rect=[new_x,new_y,new_w,new_h]
 return dest_rect
 
def show_image_rect(win_name,image,rect):
 '''
 :param win_name:
 :param image:
 :param rect:
 :return:
 '''
 x, y, w, h=rect
 point1=(x,y)
 point2=(x+w,y+h)
 cv2.rectangle(image, point1, point2, (0, 0, 255), thickness=2)
 cv_show_image(win_name, image)
 
def rgb_to_gray(image):
 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
 return image
 
def save_image(image_path, rgb_image,toUINT8=True):
 if toUINT8:
 rgb_image = np.asanyarray(rgb_image * 255, dtype=np.uint8)
 if len(rgb_image.shape) == 2: # 若是灰度图则转为三通道
 bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_GRAY2BGR)
 else:
 bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
 cv2.imwrite(image_path, bgr_image)
 
def combime_save_image(orig_image, dest_image, out_dir,name,prefix):
 '''
 命名标准:out_dir/name_prefix.jpg
 :param orig_image:
 :param dest_image:
 :param image_path:
 :param out_dir:
 :param prefix:
 :return:
 '''
 dest_path = os.path.join(out_dir, name + "_"+prefix+".jpg")
 save_image(dest_path, dest_image)
 
 dest_image = np.hstack((orig_image, dest_image))
 save_image(os.path.join(out_dir, "{}_src_{}.jpg".format(name,prefix)), dest_image)
 
if __name__=="__main__":
 image_path="../dataset/test_images/src.jpg"
 image = read_image(image_path, resize_height=None, resize_width=None)
 image = rgb_to_gray(image)
 orig_shape=np.shape(image)#shape=(h,w)
 orig_rect=[50,100,100,200]#x,y,w,h
 print("orig_shape:{}".format(orig_shape))
 show_image_rect("orig",image,orig_rect)
 
 dest_image=resize_image(image,resize_height=None,resize_width=200)
 dest_shape=np.shape(dest_image)
 print("dest_shape:{}".format(dest_shape))
 dest_rect=scale_rect(orig_rect, orig_shape, dest_shape)
 show_image_rect("dest",dest_image,dest_rect)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现汉诺塔递归算法经典案例
Mar 01 Python
python制作websocket服务器实例分享
Nov 20 Python
pandas.DataFrame删除/选取含有特定数值的行或列实例
Nov 07 Python
python计算两个矩形框重合百分比的实例
Nov 07 Python
详解python之heapq模块及排序操作
Apr 04 Python
Python实现Mysql数据统计及numpy统计函数
Jul 15 Python
Pythonic版二分查找实现过程原理解析
Aug 11 Python
python如何使用腾讯云发送短信
Sep 17 Python
python opencv肤色检测的实现示例
Dec 21 Python
Pytorch 中的optimizer使用说明
Mar 03 Python
Pytorch中Softmax与LogSigmoid的对比分析
Jun 05 Python
Python OpenCV超详细讲解读取图像视频和网络摄像头
Apr 02 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
Apr 18 #Python
python点击鼠标获取坐标(Graphics)
Aug 10 #Python
python matplotlib库直方图绘制详解
Aug 10 #Python
python字典的遍历3种方法详解
Aug 10 #Python
python命名空间(namespace)简单介绍
Aug 10 #Python
简单介绍python封装的基本知识
Aug 10 #Python
nginx黑名单和django限速,最简单的防恶意请求方法分享
Aug 09 #Python
You might like
PHP中实现汉字转区位码应用源码实例解析
2010/06/14 PHP
PHP判断一个gif图片是否为动态图片的方法
2014/11/19 PHP
PHP图形操作之Jpgraph学习笔记
2015/12/25 PHP
基于PHP实现堆排序原理及实例详解
2020/06/19 PHP
jquery动态更换设置背景图的方法
2014/03/25 Javascript
js操作IE浏览器弹出浏览文件夹可以返回目录路径
2014/07/14 Javascript
Express的路由详解
2015/12/10 Javascript
拥Bootstrap入怀——导航栏篇
2016/05/30 Javascript
jQuery通过ajax请求php遍历json数组到table中的代码(推荐)
2016/06/12 Javascript
浅谈$('div a') 与$('div>a')的区别
2016/07/18 Javascript
微信小程序 在Chrome浏览器上运行以及WebStorm的使用
2016/09/27 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
微信小程序实现自定义加载图标功能
2018/07/19 Javascript
Vuex的基本概念、项目搭建以及入坑点
2018/11/04 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
使用FastCGI部署Python的Django应用的教程
2015/07/22 Python
Python设计足球联赛赛程表程序的思路与简单实现示例
2016/06/28 Python
Python新手们容易犯的几个错误总结
2017/04/01 Python
python实现的AES双向对称加密解密与用法分析
2017/05/02 Python
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
在Python文件中指定Python解释器的方法
2019/02/18 Python
Pytorch反向求导更新网络参数的方法
2019/08/17 Python
Python Django模板之模板过滤器与自定义模板过滤器示例
2019/10/18 Python
python文件及目录操作代码汇总
2020/07/08 Python
美国折扣宠物药房:Total Pet Supply
2018/05/27 全球购物
2014两会学习心得:榜样精神伴我行
2014/03/17 职场文书
勤俭节约演讲稿
2014/05/08 职场文书
个人作风建设总结
2014/10/23 职场文书
大学生村官工作心得体会
2016/01/23 职场文书
创业计划书之酒店
2019/08/30 职场文书
python opencv旋转图片的使用方法
2021/06/04 Python
vue-router中hash模式与history模式的区别
2021/06/23 Vue.js
Windows Server 2019 配置远程控制以及管理方法
2022/04/28 Servers
Windows Server 2012配置DNS服务器的方法
2022/04/29 Servers
基于Python实现西西成语接龙小助手
2022/08/05 Golang