python + opencv:如何提取形状未知的ROI并进行分析?
python + opencv: how to extract a ROI of unknown shape and analyse it?
我有一个无法解决的问题,因为我对 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图像正是轮廓内部的图像,以便仅对该区域执行阈值处理和以上所有操作,以查看我是否可以对裁剪后的图像进行更好的轮廓处理。
这个问题部分解决了我的问题:
编辑
屏蔽信息 允许我提取 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,以便我可以执行与上面所示相同的操作?想法?
编辑二
此代码
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]
至少 return 似乎是一张灰度图像。但它显示的是整个图像,而不是我期待的状态...想法?
我会将你的蒙版堆叠成原始 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
好的,我相信我找到了我要找的答案。我正在做的是:
#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)
我有一个无法解决的问题,因为我对 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图像正是轮廓内部的图像,以便仅对该区域执行阈值处理和以上所有操作,以查看我是否可以对裁剪后的图像进行更好的轮廓处理。
这个问题部分解决了我的问题:
编辑
屏蔽信息 允许我提取 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,以便我可以执行与上面所示相同的操作?想法?
编辑二
此代码
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]
至少 return 似乎是一张灰度图像。但它显示的是整个图像,而不是我期待的状态...想法?
我会将你的蒙版堆叠成原始 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
好的,我相信我找到了我要找的答案。我正在做的是:
#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)