Python OpenCV ROI区域用法介绍(OpenCV入门4)

本文将会对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()

绘制矩形步骤:

  1. 鼠标左键按下时,记录当前坐标(ix,iy),并将drawing变量设置为True
  2. 鼠标移动时,如果drawing变量为True,就在一个复制的图像上绘制矩形,并显示出来
  3. 鼠标左键松开时,将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)的指定位置。实现方法为:

  1. 先抠出img中指定位置的ROI,并获取ROI的掩码mask(灰度图像)
  2. 将logo和mask转换成掩码,得到logo_fg和mask_inv
  3. 使用cv2.bitwise_and将roi和mask_inv进行按位与操作,得到img_bg
  4. 使用cv2.bitwise_and将logo和mask进行按位与操作,得到logo_fg
  5. 使用cv2.add将img_bg和logo_fg进行加法操作,得到dst
  6. 将dst复制到img的指定位置

最后,我们将原始图像和ROI显示出来。

三、结语

本文详细介绍了Python OpenCV中的ROI区域的选取和操作方法。首先,我们可以通过指定矩形框、坐标或掩码来选取ROI。然后,我们可以对ROI进行剪切、复制或粘贴等操作。希望对大家学习OpenCV有所帮助。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平