我有一个二值图像(binary_image_full_sizes.png),我想找到中间的大椭圆形轮廓。
cv2.findContours()
函数不会返回我正在寻找的轮廓,但当我将图像缩放 1/2 时,它会找到轮廓。我怎样才能让它找到全尺寸图像的轮廓?
inverted_binary_image = cv2.imread('binary_image_full_scale.png')
white_pixels = np.sum(inverted_binary_image == 255)
# # Find Canny edges
edged = cv2.Canny(inverted_binary_image, 30, 200)
# Finding Contours
# Use a copy of the image e.g. edged.copy()
# since findContours alters the image
contours, _ = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
min_area = white_pixels / 10
filtered_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_area]
# Convert inverted_binary_image to a color image
inverted_binary_image = cv2.cvtColor(inverted_binary_image, cv2.COLOR_GRAY2BGR)
cv2.drawContours(inverted_binary_image, filtered_contours, 0, (0, 255, 0), 3)
# Save the image with drawn contours
contour_image_path = 'binary_image_with_countours_half_scaled.png'
cv2.imwrite(contour_image_path, inverted_binary_image)
图1:
图2:
诀窍是要认识到
cv2.findContours()
方法期望二值图像上的斑点为白色,正如其他人已经指出的那样。
一个简单的颜色反转就可以解决这个问题,然后你需要做的就是找出最大的轮廓是什么。
可以在这里找到一个工作示例,它以绿色显示最大的轮廓:
参考源码:
import cv2
import requests
import numpy as np
import matplotlib.pyplot as plt
# Load input image
bgr_image = cv2.imread('xVFenHPi.png')
# Convert the input image to grayscale
gray_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2GRAY)
# Invert colors so white blobs can be identified as contours
gray_image = cv2.bitwise_not(gray_image)
# Extract all contours
contours, _ = cv2.findContours(gray_image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Draw all contours found in red
all_contours_img = bgr_image.copy()
cv2.drawContours(all_contours_img, contours, -1, (0, 0, 255), 4)
# print and draw the largest contour found
largest_contour_img = bgr_image.copy()
if len(contours) == 0:
print("!!! No contours found")
exit(0)
# Find the largest contour by the area
c = max(contours, key = cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
# Draw the biggest contour in green
cv2.rectangle(largest_contour_img, (x,y), (x+w,y+h), (0,255,0), 4)
# Display the original and processed images
plt.figure(figsize=(10, 7))
plt.subplot(2, 2, 1)
plt.title('Original Image')
plt.imshow(gray_image, cmap='gray')
plt.axis('off')
plt.subplot(2, 2, 2)
plt.title('All contours')
plt.imshow(cv2.cvtColor(all_contours_img, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.subplot(2, 2, 3)
plt.title('Largest contour')
plt.imshow(cv2.cvtColor(largest_contour_img, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.tight_layout()
plt.show()