2024-04-20 13:55:53 发布
网友
我有个形象
由5个平行排列的复选框组成。在
我需要分开复选框按钮
和复选框文本
分开保存。在
图像中可以有任意数量的复选框以并行方式排列。如何分割复选框按钮和复选框文本并分别保存它们。在
我是计算机视觉新手。请指导我如何实现它。在
我已经拆分了平行排列的图像,并像下面的图像一样保存了它们。在
{a1}
这是我的工作代码,它将方形复选框和图片中的文本分开。在
# Import necessary libraries from matplotlib import pyplot as plt import cv2 # Read image image = cv2.imread('data_2/5.png') # Height and width of the image height, width = image.shape[:2] print("Dimensions of the image.") print("Height:",height) print("Width:",width) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (5,5), 0) # Finding Edges edges = cv2.Canny(gray, 60, 255) # contours -> an outline representing or bounding the shape. _,cnts, hierarchy = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(cnts, key=cv2.contourArea, reverse=True)[:10] count = 1 for contour in contours: if(count<=4): #print("Count:",count) count = count + 1 area = cv2.contourArea(contour) if area > 100000 and area < 1000: contours.remove(contour) perimeter = cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, 0.01*perimeter, True) if len(approx) == 4: cv2.circle(image, (720, 360), 5, (255,0,0), 5) cv2.drawContours(image, [approx], -1, (0, 255, 0), 2) M = cv2.moments(approx) centers = [] if M["m00"] != 0: cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) else: cX, cY = 0, 0 P1 = approx[0] P1x = P1[0][0] P1y = P1[0][1] P2 = approx[1] P2x = P2[0][0] P2y = P2[0][1] P3 = approx[2] P3x = P3[0][0] P3y = P3[0][1] P4 = approx[3] P4x = P4[0][0] P4y = P4[0][1] plt.imshow(image) plt.title('Detecting Square') plt.show() # Cropping the square_image using array slices it's a NumPy array cropped_square = image[P1y:P3y, P2x:P3x] # Cropping the text image cropped_text = image[P1y:P3y,P3x+5:width] # Displaying the cropped square and cropped text image. plt.imshow(cropped_square) plt.title('Cropped Square') plt.show() plt.imshow(cropped_text) plt.title('Cropped Text') plt.show() # Now saving the cropped square and cropped text image cv2.imwrite('results/square1.png',cropped_square) cv2.imwrite('results/text1.png',cropped_text)
上述程序的输出:
我的回答有点晚了,不过也许这会给某些人一个自相矛盾的想法。在
首先搜索图像中的轮廓并创建遮罩和最终图像以显示结果。在
对于每一个轮廓,你会找到轮廓的大小,这样可以帮助你从字母中过滤出你的盒子(盒子的尺寸更大)。对于复选标记,我找到了一个解决方案,可以根据大小和距离轮廓左侧和右侧的极端点的距离(您可以找到很多不同的标准来过滤检查点,可能还有更好的标准-我只关注您在问题中发布的图像)。在
要找到感兴趣的区域,可以使用cv2.boundingRect()找到x、y、h、w值
然后您只需在开始时创建的图像上绘制它(请注意,这些输出仅为黑白)。也许这个方法会给你一些想法。干杯!在
代码示例:
import cv2 import numpy as np img = cv2.imread('checkbox.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, threshold = cv2.threshold(gray,170,255,cv2.THRESH_BINARY_INV) im, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) final = np.zeros(gray.shape,np.uint8) mask = np.zeros(gray.shape,np.uint8) final2 = np.zeros(gray.shape,np.uint8) list1 = [] for i in range(0, len(contours)): cnt = contours[i] epsilon = 0.1*cv2.arcLength(cnt,True) approx = cv2.approxPolyDP(cnt,epsilon,True) size = cv2.contourArea(approx) extLeft = tuple(cnt[cnt[:, :, 0].argmin()][0]) extRight = tuple(cnt[cnt[:, :, 0].argmax()][0]) distance = np.sqrt((extLeft[0] - extRight[0])**2 + (extLeft[1] - extRight[1])**2) x,y,w,h = cv2.boundingRect(cnt) mask[x:x+h, y:y+w]=0 if 700 > size > 220: cv2.drawContours(mask,contours,i,255,-1) cv2.drawContours(final,contours,i,255,2) elif 16 < distance < 17 and size > 60: list1.append(cnt) elif size < 250: cv2.drawContours(final2,contours,i,(255,255,255),1) for i in list1: cv2.drawContours(final, [i], -1, (255,255,255), -1) cv2.bitwise_not(final,final) cv2.bitwise_not(final2,final2) cv2.imwrite('c_orig.png', img) cv2.imwrite('c_boxes.png', final) cv2.imwrite('c_text.png', final2) cv2.imshow('img', img) cv2.imshow('img2', final) cv2.imshow('img3', final2) cv2.waitKey(0) cv2.destroyAllWindows()
输出:
假设不管复选框的数量如何,您的图像都将遵循类似网格的模式,一个不错的选择就是尝试模板匹配。MSTM就是一个例子。在
您应该尝试使用模板匹配在图像中查找选中或未选中的框,并将区域提取到右侧。因为您已经提到一行最多可以有5个复选框,所以您可以检查图像的宽度,除以5,得到文本区域的大致大小
我已经拆分了平行排列的图像,并像下面的图像一样保存了它们。在
{a1}
这是我的工作代码,它将方形复选框和图片中的文本分开。在
上述程序的输出:
我的回答有点晚了,不过也许这会给某些人一个自相矛盾的想法。在
首先搜索图像中的轮廓并创建遮罩和最终图像以显示结果。在
对于每一个轮廓,你会找到轮廓的大小,这样可以帮助你从字母中过滤出你的盒子(盒子的尺寸更大)。对于复选标记,我找到了一个解决方案,可以根据大小和距离轮廓左侧和右侧的极端点的距离(您可以找到很多不同的标准来过滤检查点,可能还有更好的标准-我只关注您在问题中发布的图像)。在
要找到感兴趣的区域,可以使用cv2.boundingRect()找到x、y、h、w值
然后您只需在开始时创建的图像上绘制它(请注意,这些输出仅为黑白)。也许这个方法会给你一些想法。干杯!在
代码示例:
输出:
{a1}
假设不管复选框的数量如何,您的图像都将遵循类似网格的模式,一个不错的选择就是尝试模板匹配。MSTM就是一个例子。在
您应该尝试使用模板匹配在图像中查找选中或未选中的框,并将区域提取到右侧。因为您已经提到一行最多可以有5个复选框,所以您可以检查图像的宽度,除以5,得到文本区域的大致大小
相关问题 更多 >
编程相关推荐