讲解一下这段代码: def extract_img(location, img, contour=None): x, y, w, h = location # 只提取轮廓内的字符 if contour is None: extracted_img = img[y:y + h, x:x + w] else: mask = np.zeros(img.shape, np.uint8) cv2.drawContours(mask, [contour], -1, 255, cv2.FILLED) img_after_masked = cv2.bitwise_and(mask, img) extracted_img = img_after_masked[y:y + h, x:x + w] # 将提取出的img归一化成IMG_SIZE*IMG_SIZE大小的二值图 black = np.zeros((IMG_SIZE, IMG_SIZE), np.uint8) if (w > h): res = cv2.resize(extracted_img, (IMG_SIZE, (int)(h * IMG_SIZE / w)), interpolation=cv2.INTER_AREA) d = int(abs(res.shape[0] - res.shape[1]) / 2) black[d:res.shape[0] + d, 0:res.shape[1]] = res else: res = cv2.resize(extracted_img, ((int)(w * IMG_SIZE / h), IMG_SIZE), interpolation=cv2.INTER_AREA) d = int(abs(res.shape[0] - res.shape[1]) / 2) black[0:res.shape[0], d:res.shape[1] + d] = res extracted_img = skeletonize(black) extracted_img = np.logical_not(extracted_img) return extracted_img
时间: 2024-02-14 09:25:36 浏览: 73
这段代码的大致思路如下:
1. 函数`extract_img`接受参数`location`、`img`和`contour`,其中`location`是一个包含了字符位置信息的元组(x,y,w,h),`img`是原始图像,`contour`是可选参数,表示字符的轮廓。
2. 根据传入的轮廓信息,提取出字符所在的区域。如果轮廓为空,则直接根据位置信息从原始图像中提取出字符区域;如果轮廓不为空,则根据轮廓创建一个蒙版,并将蒙版与原始图像进行按位与操作,得到提取后的图像。
3. 接下来,将提取出的图像进行归一化处理,使其大小为`IMG_SIZE * IMG_SIZE`。根据字符区域的宽度和高度,进行如下操作:
- 如果宽度大于高度,则将图像的高度缩放到`IMG_SIZE`,并在黑色背景上居中放置。
- 如果高度大于宽度,则将图像的宽度缩放到`IMG_SIZE`,并在黑色背景上居中放置。
4. 使用`skeletonize`函数对归一化后的图像进行骨架化处理,以提取出字符的主要结构。
5. 对骨架化后的图像进行逻辑反转,即黑白颜色反转。
6. 返回最终提取出的二值图像。
这段代码的主要目的是根据给定的位置信息、原始图像和轮廓,提取出包含字符的区域,并对提取后的图像进行归一化、骨架化处理和二值反转,最终返回处理后的二值图像。
相关问题
这段代码是在做什么? def binary_img_segment(binary_img, original_img=None): # binary_img = skeletonize(binary_img) # plot.imshow( binary_img,cmap = 'gray', interpolation = 'bicubic') # plot.show() # 寻找每一个字符的轮廓,使用cv2.RETR_EXTERNAL模式,表示只需要每一个字符最外面的轮廓 img, contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # cv2.RETR_TREE # cv2.drawContours(img_original, contours, -1, (0, 255, 0), 2) if len(contours) > LARGEST_NUMBER_OF_SYMBOLS: raise ValueError('symtem cannot interpret this image!') symbol_segment_location = [] # 将每一个联通体,作为一个字符 symbol_segment_list = [] index = 1 for contour in contours: location = cv2.boundingRect(contour) x, y, w, h = location if (w * h < 100): continue symbol_segment_location.append(location) # 只提取轮廓内的字符 extracted_img = extract_img(location, img, contour) symbol_segment_list.append(extracted_img) if len(original_img): cv2.rectangle(original_img, (x, y), (x + w, y + h), (0, 0, 255), 3) symbols = [] for i in range(len(symbol_segment_location)): symbols.append({'location': symbol_segment_location[i], 'src_img': symbol_segment_list[i]}) # 对字符按字符横坐标排序 symbols.sort(key=lambda x: x['location'][0]) return symbols
这段代码是一个用于二值图像分割的函数。它的输入是一个二值图像(binary_img)和一个可选的原始图像(original_img)。函数的目标是找到图像中每个字符的轮廓,并将它们作为单独的字符进行分割。
首先,使用cv2.findContours函数找到二值图像中的轮廓。这里使用了cv2.RETR_EXTERNAL模式,表示只需要每个字符最外面的轮廓。函数返回的结果是轮廓的列表(contours)和轮廓的层级关系(hierarchy)。
然后,遍历每个轮廓,计算轮廓的边界框,并根据一定的条件判断是否将其作为字符进行处理。如果判断为字符,则将其边界框信息保存到symbol_segment_location列表,并从原始图像中提取出对应的字符图像,保存到symbol_segment_list列表中。
最后,对字符按照横坐标进行排序,并将每个字符的位置和对应的图像作为字典保存到symbols列表中,最后返回symbols列表。
请注意,代码中可能存在一些注释以及一些未定义的函数或变量,需要根据上下文来进行理解和补充。
if __name__ == "__main__": img_name = "img/cap.png" img = cv2.imread(img_name) gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转灰度图 bin_img = get_binary_img(gray_img) # 二值化 # print(bin_img[370][360]) #需要注意的是图像转为数组的时候 x,y是反过来的 # 边界追踪 flag1 = 0 find, start_i, start_j = get_left_up_start_pt(flag1, bin_img) # cv.circle(bin_img, (start_i, start_j), 3, (0, 0, 0), -1) # print("start_x, start_y = ", start_i, start_j) # cv.imshow("1", bin_img) contour_img = np.zeros(shape=bin_img.shape, dtype=np.uint8) contour_img += 255 flag2, contour_img = trace_contour(bin_img, find, start_i, start_j, contour_img) if flag2 == 1: find1, start_i1, start_j1 = get_left_up_start_pt(flag2, bin_img) f, contour_img = trace_contour(bin_img, find1 + 1, start_i1, start_j1, contour_img) contour_img[0] = 255 contour_img[len(contour_img) - 1] = 255 for w in range(len(contour_img)): contour_img[w][0] = 255 contour_img[w][len(contour_img[0]) - 1] = 255 cv2.imshow("img", contour_img) cv2.waitKey() cv2.destroyAllWindows()
这段代码完成了对一张图像进行边界追踪并显示结果的过程。具体实现流程如下:
1. 设置图像文件名`img_name`,读取图像并将其转换为灰度图像`gray_img`。
2. 对灰度图像进行二值化处理,得到二值化图像`bin_img`。
3. 调用`get_left_up_start_pt`函数查找左上角的起始点。
4. 创建一个与二值化图像具有相同形状和数据类型的全零数组`contour_img`,用于存储轮廓线图像。
5. 调用`trace_contour`函数进行边界追踪,得到轮廓线图像。
6. 如果边界追踪成功,则继续查找右下角的起始点并进行边界追踪,得到完整的轮廓线图像。
7. 最后将轮廓线图像显示出来。
需要注意的是,在调用`get_left_up_start_pt`函数查找起始点时,输入参数`flag`的取值为0,表示查找左上角的起始点;在调用`trace_contour`函数进行边界追踪时,输入参数`find`的值为上一步查找到的起始点找到的标志,即0或1。
阅读全文
相关推荐
















