python + opencv:如何提取形状未知的ROI并进行分析?

时间:2018-08-22 07:29:22

标签: python opencv roi

我有一个无法解决的问题,因为我不太精通python和opencv。

假设我有一个图像,我将其转换为灰度,将其设置为阈值,进行一些扩张和腐蚀,最后可以检索到轮廓列表。一些代码:

    imfile = path + f
    origimage = cv.imread(imfile)

    #from RGB to grayscale
    imgray = cv.imread(imfile, cv.IMREAD_GRAYSCALE)

    #thresholding
    ret,thresholded = cv.threshold(imgray,chosenThresh,255,cv.THRESH_BINARY)

    dKernel = np.ones((12,12),np.uint8)
    opened = cv.morphologyEx(thresholded, cv.MORPH_CLOSE, dKernel)

    #the kernel
    sharpkrnl = np.array([[0,-1,0], [-1,5,-1], [0,-1,0]])
    sharpened = cv.filter2D(opened, -1, sharpkrnl)
    sharpened = cv.bitwise_not(sharpened)

    #find contours
    h, w = sharpened.shape[:2]
    _, contours0, hierarchy = cv.findContours(sharpened.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    contours = [cv.approxPolyDP(cnt, 3, True) for cnt in contours0]

现在的问题是...我遍历找到的轮廓,如果其中一些轮廓不符合我的要求,特别是如果轮廓太大,我想获得与内部轮廓完全相同的图像的ROI轮廓以执行阈值处理,并且仅对该区域执行所有上述操作,以查看是否可以对裁剪后的图像进行更好的 contouring

此问题部分解决了我的问题:How to crop the internal area of a contour?

编辑

提供信息使我能够提取ROI,但是我还需要具有与原始颜色相同颜色的精确图像,以便执行阈值处理和所有其他操作。我提到的答案中提供的代码需要灰度图像。这是原始代码:

import numpy as np
import cv2
img = cv2.imread('...', 0) # Read in your image
contours, _ = cv2.findContours(...) # Your call to find the contours
idx = ... # The index of the contour that surrounds your object
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = img[mask == 255]
另一方面,我在上面的代码中有 imgray 。与我发现的示例中的相同吗?我应该怎么做才能获得包含 imgray 的ROI,这样我就可以执行与上述相同的操作?想法?

EDIT II

此代码

mask = np.zeros_like(imgray) # Create mask where white is what we want, black otherwise
cv.drawContours(mask, [c], -1, 255, -1) # Draw filled contour in mask
out = np.zeros_like(imgray) # Extract out the object and place into output image
out[mask == 255] = imgray[mask == 255]

似乎至少返回了灰度图像。但这是在显示整个图像,而不是我所期望的国家……想法?

2 个答案:

答案 0 :(得分:0)

我会将您的蒙版堆叠为原始3通道图像的形状,然后将其应用于原始图像。例如,

import numpy as np
mask = np.stack((mask,)*3,-1) # make the mask 3 channel 
out = np.empty_like(origimage) # make container for output 
out[mask==255]=origimage[mask==255] # fill the container 

答案 1 :(得分:0)

好的,我相信我找到了想要的答案。我正在做的事情如下:

#by doing so I am getting a ROI over the imgray image
#which can be used to, later, perform analysis
mask = np.zeros_like(imgray) # Create mask where white is what we want, black otherwise
cv.drawContours(mask, [c], -1, 255, -1) # Draw filled contour in mask
out = np.zeros_like(imgray) # Extract out the object and place into output image
out[mask == 255] = imgray[mask == 255]

#then simply proceed with the analysis:
chosenThresh = 120
ret,thresholded = cv.threshold(out,chosenThresh,255,cv.THRESH_BINARY)

dKernel = np.ones((12,12),np.uint8)
opened = cv.morphologyEx(thresholded, cv.MORPH_CLOSE, dKernel)