1 回答

TA貢獻2019條經驗 獲得超9個贊
您可以執行以下處理步驟:
使用 將圖像閾值設置為二進制圖像。
這不是必須的,但在你的情況下,灰色陰影看起來并不重要。cv2.threshold
使用閉合形態學操作,用于閉合二進制圖像中的小間隙。
與參數一起使用,用于獲取白色聚類周圍的等值線(周長)。
cv2.findContours
cv2.RETR_EXTERNAL
修改“不良輪廓”的邏輯,僅當面積較大時才返回 true(假設您只想清理大三個輪廓)。
以下是更新的代碼:
### 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) # Find areas
return peri > 50 # Large area is considered "bad"
### DATA PROCESSING ###
image = cv2.imread("025.jpg") # Load a picture
gray = 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-opencv
thresh_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 intensity
image_cleaned = gray
# 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):
# Draw black contour on gray image, instead of using a mask
cv2.drawContours(image_cleaned, [c], -1, 0, -1)
#cv2.imshow("Adopted mask", mask) # Plot
cv2.imshow("Cleaned image", image_cleaned) # Plot
cv2.imwrite("cleaned_025.jpg", image_cleaned) # Write in a file
cv2.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 np
import imutils
import cv2
def 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 picture
gray = 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-opencv
thresh_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 intensity
image_cleaned = gray
# 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, 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 threshold
ret, thresh_gray = cv2.threshold(image_cleaned, 150, 255, cv2.THRESH_BINARY)
# Use "dilate" with small radius
thresh_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 contours
for 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)
###########################################################################
標記輪廓:
添加回答
舉報