使用Python从图像中删除不需要的连接像素

我是使用Python进行图像处理的初学者,因此我需要帮助。我正在尝试使用下面发布的代码从图片中删除连接像素的区域。实际上,它有效但并不好。我想要的是从我的图像中删除像素区域,例如下面报告的图片中标记为红色的区域,以获得干净的图片。为连接的像素的检测到的区域的尺寸设置最小和最大限制也很棒。带有标记区域的图片示例 1 具有标记区域的图片示例 2

http://img3.mukewang.com/62e88bbf0001c72d03600353.jpg

这是我目前的代码:


### LOAD MODULES ###

import numpy as np

import imutils

import cv2


def is_contour_bad(c): # Decide what I want to find and its features

    peri=cv2.contourArea(c, True) # Find areas

    approx=cv2.approxPolyDP(c, 0.3*peri, True) # Set areas approximation

    return not len(approx)>2 # Threshold to decide if add an area to the mask for its removing (if>2 remove)



### DATA PROCESSING ###

image=cv2.imread("025.jpg") # Load a picture

gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Convert to grayscale

cv2.imshow("Original image", image) # Plot


edged=cv2.Canny(gray, 50, 200, 3) # Edges of areas detection

cnts=cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) # Find contours: a curve joining all the continuous points (along the boundary), having same color or intensity

cnts=imutils.grab_contours(cnts)


mask=np.ones(image.shape[:2], dtype="uint8")*255 # Setup the mask with white background

# Loop over the detected contours

for c in cnts:

    # If the contour satisfies "is_contour_bad", draw it on the mask

    if is_contour_bad(c):

        cv2.drawContours(mask, [c], -1, 0, -1) # (source image, list of contours, with -1 all contours in [c] pass, 0 is the intensity, -1 the thickness)


image_cleaned=cv2.bitwise_and(image, image, mask=mask) # Remove the contours from the original image

cv2.imshow("Adopted mask", mask) # Plot

cv2.imshow("Cleaned image", image_cleaned) # Plot

cv2.imwrite("cleaned_025.jpg", image_cleaned) # Write in a file


精慕HU
浏览 352回答 1
1回答

慕少森

您可以执行以下处理步骤:使用 将图像阈值设置为二进制图像。这不是必须的,但在你的情况下,灰色阴影看起来并不重要。cv2.threshold使用闭合形态学操作,用于闭合二进制图像中的小间隙。与参数一起使用,用于获取白色聚类周围的等值线(周长)。cv2.findContourscv2.RETR_EXTERNAL修改“不良轮廓”的逻辑,仅当面积较大时才返回 true(假设您只想清理大三个轮廓)。以下是更新的代码:### LOAD MODULES ###import numpy as npimport imutilsimport cv2def is_contour_bad(c): # Decide what I want to find and its features    peri = cv2.contourArea(c) # Find areas    return peri > 50 # Large area is considered "bad"### DATA PROCESSING ###image = cv2.imread("025.jpg") # Load a picturegray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Convert to grayscale# Convert to binary image (all values above 20 are converted to 1 and below to 0)ret, thresh_gray = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)# Use "close" morphological operation to close the gaps between contours# https://stackoverflow.com/questions/18339988/implementing-imcloseim-se-in-opencvthresh_gray = cv2.morphologyEx(thresh_gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)));#Find contours on thresh_gray, use cv2.RETR_EXTERNAL to get external perimeter_, cnts, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Find contours: a curve joining all the continuous points (along the boundary), having same color or intensityimage_cleaned = gray# Loop over the detected contoursfor c in cnts:    # If the contour satisfies "is_contour_bad", draw it on the mask    if is_contour_bad(c):        # Draw black contour on gray image, instead of using a mask        cv2.drawContours(image_cleaned, [c], -1, 0, -1)#cv2.imshow("Adopted mask", mask) # Plotcv2.imshow("Cleaned image", image_cleaned) # Plotcv2.imwrite("cleaned_025.jpg", image_cleaned) # Write in a filecv2.waitKey(0)cv2.destroyAllWindows()结果:标记用于测试的轮廓:for c in cnts:    if is_contour_bad(c):        # Draw green line for marking the contour        cv2.drawContours(image, [c], 0, (0, 255, 0), 1)结果:仍有工作要做...更新两个迭代方法:第一次迭代 - 删除大轮廓。第二次迭代 - 删除小而明亮的轮廓。代码如下:import numpy as npimport imutilsimport cv2def is_contour_bad(c, thrs): # Decide what I want to find and its features    peri = cv2.contourArea(c) # Find areas    return peri > thrs # Large area is considered "bad"image = cv2.imread("025.jpg") # Load a picturegray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Convert to grayscale# First iteration - remove the large contour############################################################################ Convert to binary image (all values above 20 are converted to 1 and below to 0)ret, thresh_gray = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)# Use "close" morphological operation to close the gaps between contours# https://stackoverflow.com/questions/18339988/implementing-imcloseim-se-in-opencvthresh_gray = cv2.morphologyEx(thresh_gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)));#Find contours on thresh_gray, use cv2.RETR_EXTERNAL to get external perimeter_, cnts, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Find contours: a curve joining all the continuous points (along the boundary), having same color or intensityimage_cleaned = gray# Loop over the detected contoursfor c in cnts:    # If the contour satisfies "is_contour_bad", draw it on the mask    if is_contour_bad(c, 1000):        # Draw black contour on gray image, instead of using a mask        cv2.drawContours(image_cleaned, [c], -1, 0, -1)############################################################################ Second iteration - remove small but bright contours############################################################################ In the second iteration, use high thresholdret, thresh_gray = cv2.threshold(image_cleaned, 150, 255, cv2.THRESH_BINARY)# Use "dilate" with small radiusthresh_gray = cv2.morphologyEx(thresh_gray, cv2.MORPH_DILATE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,2)));#Find contours on thresh_gray, use cv2.RETR_EXTERNAL to get external perimeter_, cnts, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Find contours: a curve joining all the continuous points (along the boundary), having same color or intensity# Loop over the detected contoursfor c in cnts:    # If the contour satisfies "is_contour_bad", draw it on the mask    # Remove contour if  area is above 20 pixels    if is_contour_bad(c, 20):        # Draw black contour on gray image, instead of using a mask        cv2.drawContours(image_cleaned, [c], -1, 0, -1)###########################################################################标记轮廓:
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python