如何快速檢測兩張截圖中文字的相似度?
舉個例子,
圖一:圖二:上面兩張圖的內容都是: 太年輕太幼稚
文字相同,但是排版不同。除了通過OCR將截圖中的文字提取出來之外(考慮到可能有很長的文字),還有什麼更高效更便捷的演算法能夠計算這兩張截圖中的文字的相似度?
樓主你給我搞的這個題,excited,哈哈。
只收你 500,樓主你也別嫌貴,還不打折。
看描述樓主你還是比較 naive 的所以我也就不和你多說了,看效果吧。。。(識得唔識得呀?)
其實只要按照基本(方)法,識別手寫也可以呀(只要你加得起錢的話),哇哈哈哈哈哈哈哈哈
本來中國有句古話叫「悶聲大發財」,我什麼都不講這是最好的。但是看樓主你那麼熱情啊,我一句都不說也不好。我現在是作為一個老碼農,我不是圖像處理模式識別專家,但是我見得太多了,我有這個必要講一點編程的經驗。
作為以前的碼農,有一點好,西方的哪個網站上不去?西方這套理論,我很多年前就談笑風生了。這個程序寫了幾十分鐘也沒什麼別的,大概就是三件事:一個,確立文字矩形;第二個,把矩形解出來識別;第三個,就是「三個對比」。如果說還有一點別的事情就是矩形修正,還有就是代碼的編寫也是費了功夫的,但這些都是次要的,主要就是上面三件事。我實在我也不是謙虛,很慚愧,就只做了一點微小的工作。這問題確實可以不用ocr,稍微用點心的話,就能跑出比ocr好的結果了。
cross-correlation. 核心代碼兩行python就夠了。
中間那張圖是從google搜的,所以字體也是不完全相同的,感覺大小比例好像也不一樣http://i1.kym-cdn.com/entries/icons/facebook/000/011/632/shaonian.pngfrom skimage.feature import match_template
result = match_template(img1, img2)
============
給定兩篇文章的圖片,如果排版不一樣,只要在一張圖片找到幾個anchor point,然後用cross-correlation 從另外一張圖片找到對應的anchor point,兩個圖片就能重新對齊上。初始的 anchor point,也是有現成的方法,中文的話,還要把有重合的bounding box合成一個大bounding box,英文就沒這個問題。=============都是些圖片基本的信號處理,其實ocr也就是基於這些基本的東西,倒騰來倒騰去,折騰出結果。im2, cnts, hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
先做segmentation,然後對比。
請自行完成畢業論文。
OCR 的效果一定比你自己再發明一種「template」要好。
好像樓主問的是相似度,這個怎麼定義呢?是編輯距離嗎?還是說字元相近也算?比如,「太年輕太幼稚」vs「大年輕大幼稚」vs「不年輕不幼稚」,這兩兩編輯距離一樣,但「太」和「大」顯然字形上更接近。如果按編輯距離,那隻能做文字識別了,如果是字形,字體也會有影響,直接訓練一個回歸吧
基於 如何快速檢測兩張截圖中文字的相似度? - 知乎用戶的回答 的完整 python 代碼:
#!/usr/bin/env python2
import cv2
def intersected(rc1, rc2):
if rc1[0] &> rc2[2]: return False
if rc1[1] &> rc2[3]: return False
if rc2[0] &> rc1[2]: return False
if rc2[1] &> rc1[3]: return False
return True
def segment(grey):
_, thresh = cv2.threshold(grey, 20, 255, cv2.THRESH_BINARY_INV)
countours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
rcs = map(cv2.boundingRect, countours)
rcs = [(rc[0], rc[1], rc[0]+rc[2], rc[1]+rc[3]) for rc in rcs]
# clustering
clusters = range(len(rcs))
for i, rc in enumerate(rcs):
for j, irc in enumerate(rcs[i+1:]):
idx = i+j+1
if clusters[idx] != clusters[i] and intersected(rc, irc):
if clusters[idx] &> clusters[i]:
clusters[idx] = clusters[i]
else:
clusters[i] = clusters[idx]
def cluster(v):
indices = [i for i, x in enumerate(clusters) if x == v]
xmin = min(rcs[idx][0] for idx in indices)
ymin = min(rcs[idx][1] for idx in indices)
xmax = max(rcs[idx][2] for idx in indices)
ymax = max(rcs[idx][3] for idx in indices)
return xmin, ymin, xmax, ymax
rcs = map(cluster, set(clusters))
h = int(sum((rc[3]-rc[1]) for rc in rcs)) / len(rcs)
w = thresh.shape[1]
return sorted(rcs, key=lambda rc: int(rc[1])/h*w+rc[0]), thresh
def main(path):
im = cv2.imread(path)
# segmentation
grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
rcs, thresh = segment(grey)
# drawing
draw = im.copy()
for i, rc in enumerate(rcs):
cv2.rectangle(draw, rc[0:2], rc[2:4], (0, 0, 255))
cv2.putText(draw, str(i), (rc[0], rc[3]), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0))
#cv2.drawContours(draw, countours, i, (255, 0, 0))
cv2.imshow(path, draw)
cv2.imwrite(path + "_draw.png", draw)
return thresh, rcs
if __name__ == "__main__":
main("1.png")
main("2.png")
cv2.waitKey(0);
OCR技術 百度有類似的開源工具OCR文字識別百度OCR文字識別__API服務_API服務_API Store
本答案值1000
先說原理,不過說完誰都懂了,應該不會給錢了。
原理是,前面的人已經說了,就是取字,好了,已單個漢字為單位,每個漢字表示為一個小的01矩陣。排成一個數列。兩張圖就有兩個數列。但是子的大小,出現順序可能不一樣,怎麼比?大小是可以通過等比縮放歸一化的。怎麼比?矩陣相似度唄。查文獻唄。一串矩陣與另外一串矩陣怎麼比?記得計算字元串的相似度的演算法嗎?沒錯就用它。重寫比較的規則而已。行了,大功告成。取字形成字串矩陣,歸一化,求字串相似度。至於順序的問題,不會有太大影響,也可以從演算法上迴避。識別文字,規整的容易識別。如果還要語義分析,那就難了
OCR+simhash?? 好複雜的樣子啊
2013全國數學建模比賽有過相似的題目,題目是碎紙片的還原。這方面我們問過圖像識別的教授,他說不用做得那麼複雜的。後來我們的做法基本同理學院的數學教授槍手一樣。圖片都是像素組成,兩張不同的圖片只需要逐點比較就知道了,比如第一列有0個黑點,第二列有三個,直到找到一列有不同的黑點數肯定就是差異之處。當時候我們是用matlab處理。。。。
好好學習,天天向上
Halcon演算法軟體包裡面有個基於組件的匹配演算法題主可以參考一下,OCR如果不是要識別這兩個圖片裡面的字可能還用不到。
比對連通域?
1.這個的邊緣特徵還是比較好的,主要是縮放,那麼可以用標準的基於邊緣的模版匹配,生成模版的時候有縮放2。考慮旋轉縮放不變,可以用特徵點匹配 3,其它比較變態的,比如shape context 抗旋轉縮放抗變形 4。機器學習類的吧,由於有縮放,rcnn比較適合,分割識別同時完成,好處是不用糾結分割方法。壞處是樣本和訓練
推薦閱讀: