1 回答

TA貢獻1807條經驗 獲得超9個贊
這是一個可能的解決方案。當然,您必須調整一些參數...
我的示例代碼的作用:
應用并反轉()圖像以獲得具有黑色背景和白色字母的二進制圖像
threshold
bitwise_not
應用一個小來合并一些小元素并減少檢測次數
dilate
用于...查找等值線:)
findContours
計算和對于每個輪廓,返回檢測到寫入的矩形(區域可用于過濾不需要的小元素)
boundingRect
area
準備一個與輪廓和矩形重疊源圖像的圖像(這部分只是為了調試所必需的)
檢測后,代碼繼續創建所需的新“紋理圖像”:
total_width
是所有矩形寬度的總和mean_height
是所有正交高度的平均值total_lines
是新圖像中的行數;計算自 和 ,因此生成的圖像近似為正方形total_width
mean_height
在循環中,我們將每個矩形從圖像復制到
src
newImg
curr_line
并跟蹤粘貼矩形的位置curr_width
src
我曾經將每個新矩形混合到 ;這類似于photoshop中的“變暗”混合模式
cv.min()
newImg
顯示檢測結果的圖像:
生成的紋理圖像:
一個代碼...
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()
添加回答
舉報