使用opencv python从图像中提取多个ROI

Posted

技术标签:

【中文标题】使用opencv python从图像中提取多个ROI【英文标题】:Extract multiple ROIs from an image using opencv python 【发布时间】:2019-07-17 05:23:28 【问题描述】:

我正在开发一个程序,该程序需要从图像中选择四个点击点,并将每个点击点周围的 140x140 子部分存储在数据库中。我试图将多个图像子部分存储在一个列表中,但我做不到。

下面附上我用来获取单击点的代码。

import cv2
refPt = []
cropping = False

def click_and_crop(event, x, y, flags, param):
    global refPt, cropping

    if event == cv2.EVENT_LBUTTONUP:
        Pt = (x, y)
        refPt=[(x-70,y+70)]
        refPt.append((x+70,y-70))
        cropping = True
        cv2.rectangle(image, refPt[0], refPt[1], (0, 255, 0), 2)

image = cv2.imread('bookscene.jpg')
clone = image.copy()
cv2.namedWindow("image")
cv2.setMouseCallback("image", click_and_crop)

while True:
    cv2.imshow("image", image)
    key = cv2.waitKey(1) & 0xFF

    #reset
    if key == ord("r"):
        image = clone.copy()
    #crop
    elif key == ord("c"):
        break


if len(refPt) == 2:
    roi = clone[refPt[1][1]:refPt[0][1], refPt[0][0]:refPt[1][0]]
    cv2.imshow("ROI", roi)
    cv2.waitKey(0)

cv2.destroyAllWindows()

【问题讨论】:

【参考方案1】:

通过refPt=[(x-70,y+70)],您可以为每次点击重置每个列表。您必须附加鼠标 x/y 并稍后计算矩形,或者将两个角点存储在一起。

我使用你的代码创建了一个显示你想要的行为的要点:

import cv2
refPt = []

def show():
    global image, refPt
    # create a copy so the drawn rectangles wont show up in subimages
    img_copy = image.copy()
    # create a subimage in a separate window
    # similar code can be used that checks if 4 points are selected, then saves the subimages and exits script
    i = 0
    for rect in refPt:
        subimage = img_copy[rect[0][1]:rect[1][1],rect[0][0]:rect[1][0]]
        cv2.imshow("image"+str(i), subimage)
        i += 1
    # draw rectangle on full image 
    for rect in refPt:
        cv2.rectangle(img_copy, rect[0], rect[1], (0, 255, 0), 2)
    # show full image
    cv2.imshow("image", img_copy)


def click_and_crop(event, x, y, flags, param):
    global refPt
    if event == cv2.EVENT_LBUTTONUP:
        # create tuples with two opposite cornerpoints and add to list
        point_a = (x-70,y-70)
        point_b = (x+70,y+70)
        refPt.append((point_a,point_b))
        # show images
        show()


# load and display image
image = cv2.imread('opencv-template-matching-python-tutorial.jpg')
cv2.namedWindow("image")
cv2.setMouseCallback("image", click_and_crop)
show()

cv2.waitKey(0)
cv2.destroyAllWindows()

【讨论】:

【参考方案2】:

试试下面的代码,它可能会给你一个解决方案。绘制正确的边界框后按“Enter”或“Space”并选择下一个 ROI,完成选择 ROI 后按“Esc”

image= cv.imread("sample.jpg")
roi_positions = cv.selectROIs("Select ROIs",image)
cv.destroyWindow("Select ROIs")
print("ROI Position is: ".format(roi_position))

【讨论】:

以上是关于使用opencv python从图像中提取多个ROI的主要内容,如果未能解决你的问题,请参考以下文章

在 Python、OpenCV 中使用切片从图像中提取区域

如何使用 Python 和 OpenCV 裁剪图像中的多个 ROI

在OpenCV Python中检测/提取图像之间的最大差异

在python3下使用OpenCV 抓取摄像头图像提取蓝色

OpenCV-Python系列八:提取图像轮廓

OpenCV+Python特征提取算法与图像描述符之SIFT / SURF / ORB