OpenCV轮廓。无法找到给定图像的目标轮廓

1 投票
1 回答
71 浏览
提问于 2025-04-13 01:47

[][1]

这是我需要进行轮廓检测的图片。我想要检测矩形内外的字符轮廓,但不想检测矩形本身。第二张我附上的图片是我想要的结果。

enter image description here

现在这是我到目前为止尝试的方法:

import cv2

# Read the image
image = cv2.imread('fig1.jpg')

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

# Apply histogram equalization to enhance contrast
equalized = cv2.equalizeHist(gray)

# Apply Gaussian blur to the equalized image
blurred = cv2.GaussianBlur(equalized, (5, 5), 0)

# Apply Laplacian operator to detect edges
edges = cv2.Laplacian(blurred, cv2.CV_64F)

# Apply thresholding to create a binary image
_, edges_binary = cv2.threshold(edges, 20, 255, cv2.THRESH_BINARY)

# Convert edges_binary to the appropriate data type (CV_8UC1)
edges_binary = edges_binary.astype(np.uint8)

# Find contours of the edges
contours, _ = cv2.findContours(edges_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Draw the sides of the rectangle (for visualization)
cv2.drawContours(image, contours, -1, (255, 255, 255), 2)

# Get the bounding box of the rectangle
x, y, w, h = cv2.boundingRect(contours[0])

# Omit the sides of the rectangle from the binary image
edges_binary[y:y+h, x:x+w] = 0
# Find contours in the modified binary image
contours, _ = cv2.findContours(edges_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Draw contours on the original image
cv2.drawContours(image, contours, -1, (0, 255, 0), 2)

# Display the result
cv2.imshow('Contour Detection', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

enter image description here

我觉得我离目标很近了。我尝试了几种其他的方法,但这个方法产生的结果最接近我想要的。我上周才学会OpenCV,所以有没有人能告诉我我还可以尝试什么?

1 个回答

1

你可以利用轮廓面积来避免处理大的外部矩形。试试下面的代码。最终的结果会显示字母和符号的边框。希望这对你有帮助。

import cv2
import numpy as np

#READ IMAGE AND APPLY THRESHOLD
image = cv2.imread("letters.jpg")
grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresholded_image = cv2.threshold(grayscale_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

#FIND THE CONTOURS IN IMAGE
contours, hierarchy = cv2.findContours(thresholded_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_image = np.zeros_like(thresholded_image)

#SELECT CONTOURS WHICH ARE SMALL, LESS AREA COMPARED TO LARGE RECTANGLE
selected_ctr =[]
selected_bounding_rect = []
for ctr in contours:
    if cv2.contourArea(ctr) < 1000: #ADJUST THIS ACCORDING TO YOUR NEED.
        selected_ctr.append(ctr) #SELECT CONTOUR
        selected_bounding_rect.append(cv2.boundingRect(ctr)) #GET BOUNDING BOX

#DRAW CONTOURS OF THE FOUND LETTERS AND SYMBOLS
cv2.drawContours(contour_image, selected_ctr, -1, 255, thickness=1)
cv2.imwrite("letters_ctr.jpg",contour_image) # SAVE CONTOUR IMAGE

#DRAW THE SELECTED  RECTANGLES
for rect in selected_bounding_rect:
    image_rect = cv2.rectangle(image, rect,  (0, 255, 0) , 1)
cv2.imwrite("letters_rect.jpg",image_rect) #SAVE RECTANGLE DRAWN IMAGE

输出结果:

在这里输入图片描述

撰写回答