您尝试将更大的图像放在更小的区域 - 但它们必须相同。
您可以获得两个对象的形状,并获得 min() 的宽度和高度并使用它
h1, w1 = bg[5:5+h, left:left+w].shape
h2, w2 = img[y:y+h, x:x+w].shape
min_h = min(h1, h2)
min_w = min(w1, w2)
bg[5:5+min_h, left:left+min_w] = img[y:y+min_h, x:x+min_w]
编辑:
或者也许您应该使用x,y 而不是5 和left(也可以使用5)
bg[y:y+h, x:x+w] = img[y:y+h, x:x+w]
也许您应该创建与img 相同大小的bg(调整大小后)
h1, w1 = img.shape
bg = np.zeros((h1, w1), np.uint8)
编辑:
包含其他更改的完整工作代码。
我以 RGB 格式读取图像以查看它发现了什么轮廓,因为它似乎发现了一些与您预期不同的东西。
import cv2
import numpy as np
print('CV:', cv2.__version__)
img_color = cv2.imread("ZzSgt.png", cv2.IMREAD_UNCHANGED)
h, w = img_color.shape[:2]
print('original shape (W,H):', w, h)
img_color = cv2.resize(img_color, (w*5, h*5))
h, w = img_color.shape[:2]
print('resized shape (W,H) :', w, h)
img = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)
# Threshold the image and find the contours
_, thresh = cv2.threshold(img, 123, 255, cv2.THRESH_BINARY_INV)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Create a white background image to paste the letters on
bg = np.full((h, w), 255, np.uint8)
# Create image to display contours
img_contours = np.full((h, w, 3), 255, np.uint8)
left = 5
# Iterate through the contours
for contour, h in zip(contours, hierarchy[0]):
# Ignore inside parts (circle in a 'p' or 'b')
if h[3] == -1:
# Get the bounding rectangle
x, y, w, h = cv2.boundingRect(contour)
print('contour (X,Y,W,H):', x, y, w, h)
# Paste it onto the background
h1, w1 = bg[5:5+h, left:left+w].shape
h2, w2 = img[y:y+h, x:x+w].shape
min_h = min(h1, h2)
min_w = min(w1, w2)
bg[5:5+min_h, left:left+min_w] = img[y:y+min_h, x:x+min_w]
left += (w + 5)
# Copy color regions and draw contours
img_contours[y:y+h, x:x+w] = img_color[y:y+h, x:x+w]
img_contours = cv2.drawContours(img_contours, [contour], 0, (0,0,255))
cv2.imshow('contours', img_contours)
cv2.imshow('background', bg)
cv2.waitKey()
cv2.destroyAllWindows()
轮廓
背景
编辑:
如果我修改图像img = ~img 并将阈值从123 更改为30,我会得到更好的结果
阈值
轮廓
背景(现在我发现它的大小甚至可以达到 (75, 255) 或更安全的 (100, 300))
import cv2
import numpy as np
print('CV:', cv2.__version__)
#img_color = cv2.imread("captcha.png", cv2.IMREAD_UNCHANGED)
img_color = cv2.imread("ZzSgt.png", cv2.IMREAD_UNCHANGED)
h, w = img_color.shape[:2]
print('original shape (W,H):', w, h)
img_color = cv2.resize(img_color, (w*5, h*5))
h, w = img_color.shape[:2]
print('resized shape (W,H) :', w, h)
img = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)
img = ~img
# Threshold the image and find the contours
_, thresh = cv2.threshold(img, 30, 255, cv2.THRESH_BINARY_INV)
cv2.imshow('thresh', thresh)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Create a white background image to paste the letters on
bg = np.full((h, w), 255, np.uint8)
# Create image to display contours
img_contours = np.full((h, w, 3), 255, np.uint8)
left = 5
# Iterate through the contours
for contour, h in zip(contours, hierarchy[0]):
# Ignore inside parts (circle in a 'p' or 'b')
if h[3] == -1:
# Get the bounding rectangle
x, y, w, h = cv2.boundingRect(contour)
print('contour (X,Y,W,H):', x, y, w, h)
# Paste it onto the background
h1, w1 = bg[5:5+h, left:left+w].shape
h2, w2 = img[y:y+h, x:x+w].shape
min_h = min(h1, h2)
min_w = min(w1, w2)
bg[5:5+min_h, left:left+min_w] = img[y:y+min_h, x:x+min_w]
left += (w + 5)
# Copy (color) region and draw contour
img_contours[y:y+h, x:x+w] = img_color[y:y+h, x:x+w]
img_contours = cv2.drawContours(img_contours, [contour], 0, (0,0,255))
cv2.imshow('contours', img_contours)
cv2.imshow('background', bg)
cv2.waitKey()
cv2.destroyAllWindows()