猿问

用opencv python连接/合并图像

我正在尝试从手写手稿中创建基于纹理的图像。经过一些预处理后输入图像(文本行的二进制图像形成IAM数据库),使用垂直轮廓投影将行分割成单词/字符。分割的单词/字符的大小不同,我想将其连接起来/合并以形成所需的基于纹理的图像。输出图像的大小使得串联变得不可能。我正在使用openCV和python来做到这一点,我想要一些想法或方法来完成这样的任务。这种方法的灵感来自这篇文章:R. K. Hanusiak的“使用基于纹理的特征进行作家验证”,文章链接在219-220页。

与质心相关的串联图像

左侧的文本示例,右侧是基于纹理的图像


汪汪一只猫
浏览 108回答 1
1回答

函数式编程

这是一个可能的解决方案。当然,您必须调整一些参数...我的示例代码的作用:应用并反转()图像以获得具有黑色背景和白色字母的二进制图像thresholdbitwise_not应用一个小来合并一些小元素并减少检测次数dilate用于...查找等值线:)findContours计算和对于每个轮廓,返回检测到写入的矩形(区域可用于过滤不需要的小元素)boundingRectarea准备一个与轮廓和矩形重叠源图像的图像(这部分只是为了调试所必需的)检测后,代码继续创建所需的新“纹理图像”:total_width是所有矩形宽度的总和mean_height是所有正交高度的平均值total_lines是新图像中的行数;计算自 和 ,因此生成的图像近似为正方形total_widthmean_height在循环中,我们将每个矩形从图像复制到srcnewImgcurr_line并跟踪粘贴矩形的位置curr_widthsrc我曾经将每个新矩形混合到 ;这类似于photoshop中的“变暗”混合模式cv.min()newImg显示检测结果的图像:生成的纹理图像:一个代码...import cv2 as cvimport numpy as npimport mathsrc = cv.imread("handwriting.jpg")src_gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)# apply thresholdthreshold = 230_, img_thresh = cv.threshold(src_gray, threshold, 255, 0)img_thresh = cv.bitwise_not(img_thresh)# apply dilatedilatation_size = 1dilatation_type = cv.MORPH_ELLIPSEelement = cv.getStructuringElement(dilatation_type, (2*dilatation_size + 1, 2*dilatation_size+1), (dilatation_size, dilatation_size))img_dilate = cv.dilate(img_thresh, element)# find contourscontours = cv.findContours(img_dilate, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)# calculate rectangles and areasboundRect = [None]*len(contours[1])areas = [None]*len(contours[1])for i, c in enumerate(contours[1]):    boundRect[i] = cv.boundingRect(c)    areas[i] = cv.contourArea(c)# set drawing drawing = np.zeros((src.shape[0], src.shape[1], 3), dtype=np.uint8)# you can use only contours bigger than some areafor i in range(len(contours[1])):    if areas[i] > 1:        color = (50,50,0)        cv.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])), \          (int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3])), color, 2)# set newImgnewImg = np.ones((src.shape[0], src.shape[1], 3), dtype=np.uint8)*255total_width = 0mean_height = 0.0n = len(boundRect)for r in (boundRect):    total_width += r[2]    mean_height += r[3]/ntotal_lines = math.ceil(math.sqrt(total_width/mean_height))max_line_width = math.floor(total_width/total_lines)# loop through rectangles and perform a kind of copy pastecurr_line = 0curr_width = 0for r in (boundRect):    if curr_width > max_line_width:        curr_line += 1        curr_width = 0    # this is the position in newImg, where to insert source rectangle    pos = [curr_width, \           curr_width + r[2], \           math.floor(curr_line*mean_height), \           math.floor(curr_line*mean_height) + r[3] ]    s = src[r[1]:r[1]+r[3], r[0]:r[0]+r[2], :]    d = newImg[pos[2]:pos[3], pos[0]:pos[1], :]    newImg[pos[2]:pos[3], pos[0]:pos[1], :] = cv.min(d,s)    curr_width += r[2]cv.imwrite('detection.png',cv.subtract(src,drawing))cv.imshow('blend',cv.subtract(src,drawing))crop = int(max_line_width*1.1)cv.imwrite('texture.png',newImg[:crop, :crop, :])cv.imshow('newImg',newImg[:crop, :crop, :])cv.waitKey()
随时随地看视频慕课网APP

相关分类

Python
我要回答