简体   繁体   English

如何在Python中使用OpenCV提取图像的特定部分?

[英]How to extract a specific section of an image using OpenCV in Python?

I am trying to extract a portion of an image by performing Canny edge detection. 我试图通过执行Canny边缘检测来提取图像的一部分。 I have succesfully created a mask of that object. 我成功地创建了该对象的蒙版。 But when I perform a bitwise_and operation with the original image, to extract the foreground section, I am getting the following error . 但是当我对原始图像执行bitwise_and操作时,为了提取前景部分,我收到以下错误。

OpenCV Error: Assertion failed ((mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1)) in cv::binary_op, file C:\projects\opencv-python\opencv\modules\core\src\arithm.cpp, line 241
    Traceback (most recent call last):
      File "C:\Users\Boudhayan Dev\Desktop\extraction.py", line 37, in <module>
        new_image = cv2.bitwise_and(img_rgb,img_rgb,mask=mask)
    cv2.error: C:\projects\opencv-python\opencv\modules\core\src\arithm.cpp:241: error: (-215) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function cv::binary_op

My code is as follows - 我的代码如下 -

import cv2
import numpy as np

img_rgb = cv2.imread("3.jpg")
cv2.namedWindow("Original Image",cv2.WINDOW_NORMAL)

img = cv2.cvtColor(img_rgb,cv2.COLOR_RGB2HSV)
img = cv2.bilateralFilter(img,9,105,105)
r,g,b=cv2.split(img)
equalize1= cv2.equalizeHist(r)
equalize2= cv2.equalizeHist(g)
equalize3= cv2.equalizeHist(b)
equalize=cv2.merge((r,g,b))

equalize = cv2.cvtColor(equalize,cv2.COLOR_RGB2GRAY)

ret,thresh_image = cv2.threshold(equalize,0,255,cv2.THRESH_OTSU+cv2.THRESH_BINARY)
equalize= cv2.equalizeHist(thresh_image)


canny_image = cv2.Canny(equalize,250,255)
canny_image = cv2.convertScaleAbs(canny_image)
kernel = np.ones((3,3), np.uint8)
dilated_image = cv2.dilate(canny_image,kernel,iterations=1)


new,contours, hierarchy = cv2.findContours(dilated_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours= sorted(contours, key = cv2.contourArea, reverse = True)[:10]
c=contours[0]
print(cv2.contourArea(c))
final = cv2.drawContours(img, [c], -1, (255,0, 0), 3)



mask = np.zeros(img_rgb.shape,np.uint8)
new_image = cv2.drawContours(mask,[c],0,255,-1,)
new_image = cv2.bitwise_and(img_rgb,img_rgb,mask=mask)


cv2.namedWindow("new",cv2.WINDOW_NORMAL)
cv2.imshow("new",new_image)

cv2.imshow("Original Image",img)
cv2.waitKey() 

NOTE :- The code works fine if I try to perform the bitwise_and with a grayscale version of the image. 注意: - 如果我尝试使用灰度版本的图像执行bitwise_and ,则代码可以正常工作。 However RGB,HSV or any other color spaces give the error above. 但是,RGB,HSV或任何其他颜色空间会产生上述错误。

Please help. 请帮忙。


EDIT 1 - The image in question is this - 编辑1 -有问题的图像是这样的 -

3.jpeg

EDIT 2- 编辑2-

The following is the result after using Numpy method. 以下是使用Numpy方法后的结果。 As you can see, the extracted image is the same size as the orange but it does not contain the orange instead the mask itself. 如您所见,提取的图像与橙色的大小相同,但它不包含橙色而不是蒙版本身。

结果

EDIT 3- @DanMašek and @lightalchemist , I could finally extract any foreground image. 编辑3- @DanMašek和@lightalchemist,我终于可以提取任何前景图像了。

RESULT1

RESULT2

Thank you 谢谢

The error is telling you that you are trying to perform the bitwise_and operation on matrices where the entries are not integers. 该错误告诉您正在尝试对条目不是整数的矩阵执行bitwise_and操作。 I believe the matrices also have to have the same number of channels. 我相信矩阵也必须具有相同数量的通道。 This is why it works with your grayscale image but not with the HSV image. 这就是为什么它适用于您的灰度图像,而不适用于HSV图像。

Instead of using bitwise_and, it is easier and more flexible to just use numpy matrix vectorization to perform the masking like so: 而不是使用bitwise_and,使用numpy矩阵矢量化执行掩码更容易,更灵活:

mask = np.zeros_like(img_rgb, dtype=np.uint8)

# I believe you want to draw the filled in contour on the mask
# You code actually assigns the resulting mask to new_image
# But that does not affect things as drawContours modifies mask in place
mask = cv2.drawContours(mask, [c] ,0, 255, -1) 

new_image = img_rgb.copy()
new_image[mask < 255] = 0  # Set values not masked to be 0

Note that if your mask is a single channel matrix instead of a 3 channel matrix, you would have to modify the code to be 请注意,如果您的掩码是单个通道矩阵而不是3通道矩阵,则必须修改代码

new_image[mask < 255, :] = 0

I used the code provided above but only altered the line where the cv2.bitwise_and() is used: 我使用了上面提供的代码,但只更改了使用cv2.bitwise_and()的行:

new_image = cv2.bitwise_and(img_rgb, img_rgb, mask = equalize)

This is what I got and what you expected (I guess): 这就是我得到的和你的预期(我猜):

在此输入图像描述

EDIT 编辑

I get it, you want to mask your image with an image of contour having the greatest area. 我明白了,你想要用最大面积的轮廓图像来掩盖你的图像。 In the following additional snippet I have binarized the image containing the contour of greatest area to be used as mask. 在下面的附加片段中,我将包含最大区域轮廓的图像二值化,以用作遮罩。

new_image = cv2.drawContours(mask,[c], -1, (255,255,255), -1)
new_image_gray = cv2.cvtColor(new_image, cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(new_image_gray, 100, 255, cv2.THRESH_BINARY)
final = cv2.bitwise_and(img_rgb, img_rgb, mask = thresh1)

This is what I got: 这就是我得到的:

在此输入图像描述

Compared to the image above you do not see those holes inside the object of interest. 与上图相比,您不会在感兴趣的对象内看到这些洞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Python中使用OpenCV翻译图像的一小部分 - How to translate a small section of an image using OpenCV in Python 如何使用opencv和python仅从图像中提取文本部分? - How to extract the text part only from an image using opencv and python? 如何在 Python 中使用 opencv 或 PIL 提取混合到另一个图像中的图像 - How to extract an image which was blended into another using opencv or PIL in Python 使用python从opencv级联获取特定的图像横截面 - Getting specific image cross-section from opencv cascade with python 如何使用 OpenCv Python 检测图像上的特定标记 - How To Detect A Specific Mark On A Image Using OpenCv Python 如何使用 python opencv 删除文件夹中的特定图像 - how to delete specific image in folder using python opencv 使用 Python OpenCV 删除图像的黑色标题部分 - Remove black header section of image using Python OpenCV 如何使用 Python 中的正则表达式提取 JSON 字符串的特定部分? - How can I extract a specific section of a JSON string using a regex in Python? 如何使用 Python OpenCV 将图像裁剪为仅文本部分? - How to crop image to only text section with Python OpenCV? 如何使用 opencv 和 pytesseract python 提取文本? - how to extract text using opencv and pytesseract python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM