亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

用opencv python連接/合并圖像

用opencv python連接/合并圖像

汪汪一只貓 2022-08-25 14:10:21
我正在嘗試從手寫手稿中創建基于紋理的圖像。經過一些預處理后輸入圖像(文本行的二進制圖像形成IAM數據庫),使用垂直輪廓投影將行分割成單詞/字符。分割的單詞/字符的大小不同,我想將其連接起來/合并以形成所需的基于紋理的圖像。輸出圖像的大小使得串聯變得不可能。我正在使用openCV和python來做到這一點,我想要一些想法或方法來完成這樣的任務。這種方法的靈感來自這篇文章:R. K. Hanusiak的“使用基于紋理的特征進行作家驗證”,文章鏈接在219-220頁。與質心相關的串聯圖像左側的文本示例,右側是基于紋理的圖像
查看完整描述

1 回答

?
函數式編程

TA貢獻1807條經驗 獲得超9個贊

這是一個可能的解決方案。當然,您必須調整一些參數...

我的示例代碼的作用:

  • 應用并反轉()圖像以獲得具有黑色背景和白色字母的二進制圖像thresholdbitwise_not

  • 應用一個小來合并一些小元素并減少檢測次數dilate

  • 用于...查找等值線:)findContours

  • 計算和對于每個輪廓,返回檢測到寫入的矩形(區域可用于過濾不需要的小元素)boundingRectarea

  • 準備一個與輪廓和矩形重疊源圖像的圖像(這部分只是為了調試所必需的)

檢測后,代碼繼續創建所需的新“紋理圖像”:

  • total_width是所有矩形寬度的總和

  • mean_height是所有正交高度的平均值

  • total_lines新圖像中的行數;計算自 和 ,因此生成的圖像近似為正方形total_widthmean_height

  • 在循環中,我們將每個矩形從圖像復制到srcnewImg

  • curr_line并跟蹤粘貼矩形的位置curr_widthsrc

  • 我曾經將每個新矩形混合到 ;這類似于photoshop中的“變暗”混合模式cv.min()newImg

顯示檢測結果的圖像:

http://img1.sycdn.imooc.com//6307126b0001a7bf06040746.jpg

生成的紋理圖像:

http://img1.sycdn.imooc.com//630712760001f80b03440343.jpg

一個代碼...

import cv2 as cv

import numpy as np

import math


src = cv.imread("handwriting.jpg")

src_gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)


# apply threshold

threshold = 230

_, img_thresh = cv.threshold(src_gray, threshold, 255, 0)

img_thresh = cv.bitwise_not(img_thresh)


# apply dilate

dilatation_size = 1

dilatation_type = cv.MORPH_ELLIPSE

element = cv.getStructuringElement(dilatation_type, (2*dilatation_size + 1, 2*dilatation_size+1), (dilatation_size, dilatation_size))

img_dilate = cv.dilate(img_thresh, element)


# find contours

contours = cv.findContours(img_dilate, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)


# calculate rectangles and areas

boundRect = [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 area

for 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 newImg

newImg = np.ones((src.shape[0], src.shape[1], 3), dtype=np.uint8)*255

total_width = 0

mean_height = 0.0

n = len(boundRect)

for r in (boundRect):

    total_width += r[2]

    mean_height += r[3]/n


total_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 paste

curr_line = 0

curr_width = 0

for 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()



查看完整回答
反對 回復 2022-08-25
  • 1 回答
  • 0 關注
  • 124 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號