如何使用 Opencv 缩小图像中的符号
How to scale down symbols in an image using Open CV
我正在尝试使用 Open CV 缩小图像中的数字。我目前能够识别轮廓,但我很难弄清楚如何在识别后缩小数字。
这是一个示例图片:
这是我确定的等高线:
这是我用来实现此目的的代码:
import cv2
image = cv2.imread("numbers.png")
edged = cv2.Canny(image, 10, 250)
# applying closing function
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
closed = cv2.morphologyEx(edged, cv2.MORPH_CLOSE, kernel)
_, cnts,_ = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
contours = []
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
contours.append(approx)
cv2.drawContours(image, [approx], -1, (0, 255, 0), 2)
cv2.imshow("Output", image)
cv2.waitKey(0)
我希望能够在不影响图像大小的情况下使用等高线缩小数字。这可能吗?谢谢!
假设您有一个名为 "numbers.png" 的输入图像。
首先,导入有用的库并加载输入图像:
import cv2
import numpy as np
img = cv2.imread("./numbers.png", 1)
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
其次,需要对输入图像进行二值化,求出数字的外轮廓:
_, im_th = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, _ = cv2.findContours(255-im_th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
所以你可以看到检测到的轮廓将围绕数字。
第三,找到数字周围的相对边界框并找到框的中点坐标(我假设数字应该调整大小并放在底线的中心):
number_imgs = []
number_btm_mid_pos = []
for cnt in contours:
(x, y, w, h) = cv2.boundingRect(cnt)
number_imgs.append(img[y:y+h, x:x+w])
number_btm_mid_pos.append((int(x+w/2), y+h))
最后调整数字大小,放回图片,显示结果:
# resize images and put it back
output_img = np.ones_like(img) * 255
resize_ratio = 0.5
for (i, num_im) in enumerate(number_imgs):
num_im = cv2.resize(num_im, (0,0), fx=resize_ratio, fy=resize_ratio)
(img_h, img_w) = num_im.shape[:2]
# x1, y1, x2, y2
btm_x, btm_y = number_btm_mid_pos[i]
x1 = btm_x - int(img_w / 2)
y1 = btm_y - img_h
x2 = x1 + img_w
y2 = y1 + img_h
output_img[y1:y2, x1:x2] = num_im
cv2.imshow("Output Image", output_img)
cv2.imshow("Original Input", img)
cv2.waitKey()
您可以调整变量 "resize_ratio" 以确保比率符合您的预期。结果应该类似于这里的这张图片:
您可能会注意到最后一个数字“10”分开了。这是因为“1 0”被识别为两个单独的数字。为了使其完美,可以编写一些代码来测试每两个数字之间的gap/distance。然而,这将不是密切相关的,并且有点难以基于有限的测试输入来概括解决方案。所以我就到此为止了。
无论如何,祝你好运,玩得开心。
我正在尝试使用 Open CV 缩小图像中的数字。我目前能够识别轮廓,但我很难弄清楚如何在识别后缩小数字。
这是一个示例图片:
这是我确定的等高线:
这是我用来实现此目的的代码:
import cv2
image = cv2.imread("numbers.png")
edged = cv2.Canny(image, 10, 250)
# applying closing function
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
closed = cv2.morphologyEx(edged, cv2.MORPH_CLOSE, kernel)
_, cnts,_ = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
contours = []
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
contours.append(approx)
cv2.drawContours(image, [approx], -1, (0, 255, 0), 2)
cv2.imshow("Output", image)
cv2.waitKey(0)
我希望能够在不影响图像大小的情况下使用等高线缩小数字。这可能吗?谢谢!
假设您有一个名为 "numbers.png" 的输入图像。
首先,导入有用的库并加载输入图像:
import cv2
import numpy as np
img = cv2.imread("./numbers.png", 1)
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
其次,需要对输入图像进行二值化,求出数字的外轮廓:
_, im_th = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, _ = cv2.findContours(255-im_th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
所以你可以看到检测到的轮廓将围绕数字。
第三,找到数字周围的相对边界框并找到框的中点坐标(我假设数字应该调整大小并放在底线的中心):
number_imgs = []
number_btm_mid_pos = []
for cnt in contours:
(x, y, w, h) = cv2.boundingRect(cnt)
number_imgs.append(img[y:y+h, x:x+w])
number_btm_mid_pos.append((int(x+w/2), y+h))
最后调整数字大小,放回图片,显示结果:
# resize images and put it back
output_img = np.ones_like(img) * 255
resize_ratio = 0.5
for (i, num_im) in enumerate(number_imgs):
num_im = cv2.resize(num_im, (0,0), fx=resize_ratio, fy=resize_ratio)
(img_h, img_w) = num_im.shape[:2]
# x1, y1, x2, y2
btm_x, btm_y = number_btm_mid_pos[i]
x1 = btm_x - int(img_w / 2)
y1 = btm_y - img_h
x2 = x1 + img_w
y2 = y1 + img_h
output_img[y1:y2, x1:x2] = num_im
cv2.imshow("Output Image", output_img)
cv2.imshow("Original Input", img)
cv2.waitKey()
您可以调整变量 "resize_ratio" 以确保比率符合您的预期。结果应该类似于这里的这张图片:
您可能会注意到最后一个数字“10”分开了。这是因为“1 0”被识别为两个单独的数字。为了使其完美,可以编写一些代码来测试每两个数字之间的gap/distance。然而,这将不是密切相关的,并且有点难以基于有限的测试输入来概括解决方案。所以我就到此为止了。
无论如何,祝你好运,玩得开心。