本文将会对Python OpenCV中的ROI(Region of Interest,感兴趣区域)进行详细的讲解。首先,我们需要明确什么是ROI区域。在OpenCV中,ROI是指一组像素矩阵,这个矩阵包含了我们在图像处理中所关心或所需要的数据。一般来说,我们处理图像时需要对其中特定区域进行操作,而这个特定区域就是ROI。
一、ROI区域的选取
ROI区域的选取方法有多种,比较常见的有以下几种:
1. 按坐标选取
我们可以通过指定ROI区域的左上角的坐标和右下角的坐标来选取ROI。
import cv2 # 读取图像 img = cv2.imread('test.jpg') # 指定ROI的位置 x,y,w,h = 100,100,200,200 roi = img[y:y+h, x:x+w] # 在图像上画出ROI的位置 cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2) # 显示图像 cv2.imshow('img', img) # 显示ROI cv2.imshow('roi', roi) cv2.waitKey(0) cv2.destroyAllWindows()
2. 按矩形选取
我们可以通过绘制矩形来选取ROI。下面的示例代码可以通过鼠标拖动的方式绘制矩形,选取ROI。
import cv2 # 定义全局变量 drawing = False # 是否开始画矩形 ix,iy = -1,-1 # 矩形的左上角 # 鼠标的回调函数 def draw_rectangle(event,x,y,flags,param): global ix,iy,drawing,img if event == cv2.EVENT_LBUTTONDOWN: # 左键按下,开始画矩形 drawing = True ix,iy = x,y elif event == cv2.EVENT_MOUSEMOVE: # 鼠标移动,绘制矩形 if drawing == True: img_copy = img.copy() cv2.rectangle(img_copy,(ix,iy),(x,y),(0,255,0),2) cv2.imshow('image',img_copy) elif event == cv2.EVENT_LBUTTONUP: # 左键松开,结束绘制 drawing = False cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),2) cv2.imshow('image',img) # 创建窗口,并注册鼠标回调函数 img = cv2.imread('test.jpg') cv2.namedWindow('image') cv2.setMouseCallback('image',draw_rectangle) # 等待用户操作 cv2.waitKey(0) cv2.destroyAllWindows()
绘制矩形步骤:
- 鼠标左键按下时,记录当前坐标(ix,iy),并将drawing变量设置为True
- 鼠标移动时,如果drawing变量为True,就在一个复制的图像上绘制矩形,并显示出来
- 鼠标左键松开时,将drawing变量设置为False,并在原始图像上绘制矩形
3. 按掩码选取
我们可以通过指定一个掩码来选取ROI。掩码是一个与原始图像大小相同的矩阵,矩阵中元素的值为0或1,其中1表示需要选取的像素。
import cv2 import numpy as np # 读取图像 img = cv2.imread('test.jpg') # 创建掩码 mask = np.zeros(img.shape[:2], dtype=np.uint8) mask[100:300, 100:300] = 1 # 将掩码应用于原始图像 roi = cv2.bitwise_and(img, img, mask=mask) # 显示图像 cv2.imshow('img', img) cv2.imshow('mask', mask*255) cv2.imshow('roi', roi) cv2.waitKey(0) cv2.destroyAllWindows()
在上面的代码中,我们首先创建了一个大小与原始图像相同的掩码,并将其中一部分像素设置为1。然后,我们使用cv2.bitwise_and函数将掩码应用于原始图像,得到ROI。
二、ROI区域的操作
我们可以对ROI区域进行各种操作,比如剪切、复制、粘贴等。
1. 剪切ROI
我们可以通过剪切ROI来获取ROI的像素矩阵,并将其从原始图像中删除。
import cv2 # 读取图像 img = cv2.imread('test.jpg') # 将ROI抠出来 x,y,w,h = 100,100,200,200 roi = img[y:y+h, x:x+w] # 在原始图像中删除ROI img[y:y+h, x:x+w] = 0 # 显示图像 cv2.imshow('img', img) cv2.imshow('roi', roi) cv2.waitKey(0) cv2.destroyAllWindows()
在上面的代码中,我们首先将ROI抠出来,然后在原始图像中删除ROI。最后,我们将原始图像和ROI显示出来。
2. 复制ROI
我们可以通过复制ROI来创建一个副本。复制ROI的方法很简单,只需要将ROI中的像素数据拷贝到一个新的位置即可。
import cv2 # 读取图像 img = cv2.imread('test.jpg') # 将ROI复制一份到新的位置 x,y,w,h = 100,100,200,200 roi = img[y:y+h, x:x+w].copy() img[300:500, 300:500] = roi # 显示图像 cv2.imshow('img', img) cv2.imshow('roi', roi) cv2.waitKey(0) cv2.destroyAllWindows()
在上面的代码中,我们首先将ROI复制一份,并将其粘贴到原始图像的一个新位置。最后,我们将原始图像和ROI显示出来。
3. 粘贴ROI
我们可以通过粘贴ROI来将ROI覆盖到原始图像的某个位置。
import cv2 # 读取图像 img = cv2.imread('test.jpg') # 读取另一个图像 logo = cv2.imread('logo.png') logo = cv2.resize(logo, (200,200)) # 将logo覆盖到img的指定位置 x,y = 100,100 roi = img[y:y+logo.shape[0], x:x+logo.shape[1]] mask = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY) ret, mask = cv2.threshold(mask, 10, 255, cv2.THRESH_BINARY) mask_inv = cv2.bitwise_not(mask) img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv) logo_fg = cv2.bitwise_and(logo, logo, mask=mask) dst = cv2.add(img_bg, logo_fg) img[y:y+logo.shape[0], x:x+logo.shape[1]] = dst # 显示图像 cv2.imshow('img', img) cv2.imshow('logo', logo) cv2.waitKey(0) cv2.destroyAllWindows()
在上面的代码中,我们首先读取了两幅图像,然后将其中一幅图像(logo)粘贴到另一幅图像(img)的指定位置。实现方法为:
- 先抠出img中指定位置的ROI,并获取ROI的掩码mask(灰度图像)
- 将logo和mask转换成掩码,得到logo_fg和mask_inv
- 使用cv2.bitwise_and将roi和mask_inv进行按位与操作,得到img_bg
- 使用cv2.bitwise_and将logo和mask进行按位与操作,得到logo_fg
- 使用cv2.add将img_bg和logo_fg进行加法操作,得到dst
- 将dst复制到img的指定位置
最后,我们将原始图像和ROI显示出来。
三、结语
本文详细介绍了Python OpenCV中的ROI区域的选取和操作方法。首先,我们可以通过指定矩形框、坐标或掩码来选取ROI。然后,我们可以对ROI进行剪切、复制或粘贴等操作。希望对大家学习OpenCV有所帮助。