图像处理之使用人机交互截取图片
在图像处理的过程中,我们可能会遇到这样的一个场景,想要截取图像的某个区域,但是,又无法知道区域在图片的具体位置,无法通过正常的截图手段进行操作。所以,根据这一需求,我们应该想到在交互状态下去操作图像,也就是可以通过我们的鼠标进行选定某个区域,然后再进行相应的操作,当然,我们在这里是截图操作。设置一个可以选定区域且如果没有选好,还可以重新选择的需求。
在opencv中就有一些提供人机交互的参数(其实主要是鼠标的控制):
鼠标事件 :cv2.setMouseCallback()
cv2.EVENT_MOUSEMOVE 滑动
cv2.EVENT_FLAG_LBUTTON 左键拖拽
cv2.EVENT_FLAG_RBUTTON 右键拖拽
cv2.EVENT_FLAG_MBUTTON 中间拖拽
cv2.EVENT_FLAG_LBUTTON 左键拖拽
cv2.EVENT_FLAG_RBUTTON 右键拖拽
cv2.EVENT_FLAG_MBUTTON 中间拖拽
cv2.EVENT_LBUTTONDOWN 左键点击
cv2.EVENT_RBUTTONDOWN 右键点击
cv2.EVENT_MBUTTONDOWN 中间点击
cv2.EVENT_LBUTTONDBLCLK 左键双击
cv2.EVENT_RBUTTONDBLCLK 右键双击
cv2.EVENT_MBUTTONDBLCLK 中间释放
使用opencv的python接口完成以下程序。
第一步先初始化一些参数,比如(颜色,截选的矩形初始位置等):
RED = [0, 0, 255]
rect = (0, 0, 1, 1)
drawing = False
rectangle = False
rect_over = False
rect_or_mask = 100
thickness = 2
第二步定义一个用鼠标手动选定图像中某个区域的函数(主要考虑:鼠标点击、鼠标拖动和鼠标释放的情景):
定义函数:
def rectangle_roi(event, x, y, flags, param):
global img, img2, dst, drawing, mask, rectangle, rect, rect_or_mask, ix, iy, rect_over
鼠标点击:
if event == cv2.EVENT_RBUTTONDOWN:
rectangle = True
ix, iy = x, y
鼠标拖动:
elif event == cv2.EVENT_MOUSEMOVE:
if rectangle == True:
img = img2.copy()
cv2.rectangle(img, (ix, iy), (x, y), RED, thickness)
rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
rect_or_mask = 0
鼠标释放:
elif event == cv2.EVENT_RBUTTONUP:
rectangle = False
rect_over = True
cv2.rectangle(img, (ix, iy), (x, y), RED, thickness)
rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
rect_or_mask = 0
print(" Now press the key 'n' a few times until no further change \n")
最后,考虑选定区域之后,该截取此区域,另外还可以设置一个重新反复选定区域的操作。while(1):
cv2.imshow('input',img)
k = cv2.waitKey(1)
if k == 27:
break
elif k == ord('r'):
print("resetting \n")
rect = (0, 0, 1, 1)
drawing = False
rectangle = False
rect_or_mask = 100
rect_over = False
img = img2.copy()
elif k == ord('n'):
if (rect_or_mask == 0):
x1, y1, x2, y2 = rect
dst = img[(y1+2):(y1+y2-2), (x1+2):(x1+x2-2)]
cv2.imshow("dst", dst)
cv2.waitKey(0)
elif k == ord("s"):
x1, y1, x2, y2 = rect
dst = img[(y1 + 2):(y1 + y2 - 2), (x1 + 2):(x1 + x2 - 2)]
roi_title = "ROI_" + filename
cv2.imwrite(roi_title, dst)
至此,这个操作已经完成,实现的效果:
然后,截取下来的区域为:
完整代码演示:
http://download.csdn.net/download/llh_1178/9996610
感谢支持,欢迎批评与指正!
上一篇: unity人机交互—Input
推荐阅读