使用watershed作為psenet的后處理

前段時(shí)間在跑文本檢測(cè)的psenet模型秃臣,psenet的后處理過(guò)程使用了使用了一個(gè)稱為PSE(progressive scale expansion塞俱,逐步的尺度擴(kuò)張)的處理步驟來(lái)得到完整的word bbox蜘渣,作者提供了C++和Python的PSE實(shí)現(xiàn)授舟,其中使用Python版本的PSE非常緩慢塞弊。
最近在復(fù)現(xiàn)另一個(gè)文本檢測(cè)模型CRAFT的過(guò)程中肩碟,接觸到了用于分割的watershed/分水嶺算法强窖,opencv提供了watershed的函數(shù)接口cv2.watershed()
經(jīng)過(guò)簡(jiǎn)單了解之后削祈,發(fā)現(xiàn)分水嶺算法的原理其實(shí)和PSE差不多翅溺,都是通過(guò)一些最初指定的kernel脑漫,然后不斷向外擴(kuò)張來(lái)達(dá)到圖像分割的效果。于是試著用cv2.watershed()來(lái)代替Python版本的PSE處理咙崎。
相關(guān)代碼如下:

...
img = img.resize((resize_w, resize_h), Image.BILINEAR)
input_img = transform(img).unsqueeze(0).to(device)
with torch.no_grad():
    outputs = model(input_img)
    outputs = torch.sigmoid(outputs)
    score = outputs[:, 0, :, :]
    outputs = outputs > args.threshold # torch.uint8
    text = outputs[:, 0, :, :]
    kernels = outputs[:, 0:args.kernel_num, :, :] * text
score = score.squeeze(0).cpu().numpy()
text = text.squeeze(0).cpu().numpy()
kernels = kernels.squeeze(0).cpu().numpy()

tmp_marker = kernels[-1, :, :]
for i in range(args.kernel_num-2, -1, -1):
    sure_fg = tmp_marker
    sure_bg = kernels[i, :, :]
    watershed_source = cv2.cvtColor(sure_bg, cv2.COLOR_GRAY2BGR)
    unknown = cv2.subtract(sure_bg,sure_fg)
    ret, marker = cv2.connectedComponents(sure_fg)
    label_num = np.max(marker)
    marker += 1
    marker[unknown==1] = 0
    marker = cv2.watershed(watershed_source, marker)
    marker[marker==-1] = 1
    marker -= 1
    tmp_marker = np.asarray(marker, np.uint8)

label = tmp_marker
scale = (w / marker.shape[1], h / marker.shape[0])
bboxes = []
for i in range(1, label_num+1):
    # get [x,y] pair, points.shape=[n, 2]
    points = np.array(np.where(label == i)).transpose((1, 0))[:, ::-1]
    # similar to pixellink's min_area when post-processing
    if points.shape[0] < args.min_area / (args.scale * args.scale):
        continue
    #this filter op is very important, f-score=68.0(without) vs 69.1(with)
    score_i = np.mean(score[label == i])
    if score_i < args.min_score:
        continue
    rect = cv2.minAreaRect(points)
    bbox = cv2.boxPoints(rect) * scale
    bbox = bbox.astype('int32')
    bboxes.append(bbox.reshape(-1))
...

上面的代碼模擬了PSE的過(guò)程优幸,在ic15測(cè)試集上跑,速度比c++版本的PSE還快一些(使用的resnet152褪猛,速度對(duì)比:1.28fps vs 1.05fps)网杆。但是準(zhǔn)確率下降了約3個(gè)點(diǎn)(f-score:82.3 vs 85.4)。

不過(guò)我直接使用最大尺度的kernel作為watershed的源伊滋,不使用PSE的過(guò)程碳却,直接從最小scale的kernel擴(kuò)張到最大尺度的kernel,這樣得到的結(jié)果反而更好一些笑旺,f-score達(dá)到了84.2昼浦。雖然比作者提供的PSE算法低一些,但是速度更快筒主,能達(dá)到1.42fps关噪,而且代碼也挺簡(jiǎn)單的。
修改后的部分代碼:

...
sure_fg = kernels[-1, :, :]
sure_bg = text
watershed_source = cv2.cvtColor(sure_bg, cv2.COLOR_GRAY2BGR)
unknown = cv2.subtract(sure_bg,sure_fg)
ret, marker = cv2.connectedComponents(sure_fg)
label_num = np.max(marker)
marker += 1
marker[unknown==1] = 0
marker = cv2.watershed(watershed_source, marker)
marker -= 1

label = marker
...

參考資料:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末物舒,一起剝皮案震驚了整個(gè)濱河市色洞,隨后出現(xiàn)的幾起案子戏锹,更是在濱河造成了極大的恐慌冠胯,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锦针,死亡現(xiàn)場(chǎng)離奇詭異荠察,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)奈搜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門悉盆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人馋吗,你說(shuō)我怎么就攤上這事焕盟。” “怎么了宏粤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵脚翘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我绍哎,道長(zhǎng)来农,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任崇堰,我火速辦了婚禮沃于,結(jié)果婚禮上涩咖,老公的妹妹穿的比我還像新娘。我一直安慰自己繁莹,他們只是感情好檩互,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蒋困,像睡著了一般盾似。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上雪标,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天零院,我揣著相機(jī)與錄音,去河邊找鬼村刨。 笑死告抄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嵌牺。 我是一名探鬼主播打洼,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼逆粹!你這毒婦竟也來(lái)了募疮?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤僻弹,失蹤者是張志新(化名)和其女友劉穎阿浓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蹋绽,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芭毙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卸耘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片退敦。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蚣抗,靈堂內(nèi)的尸體忽然破棺而出侈百,到底是詐尸還是另有隱情,我是刑警寧澤翰铡,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布钝域,位于F島的核電站,受9級(jí)特大地震影響两蟀,放射性物質(zhì)發(fā)生泄漏网梢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一赂毯、第九天 我趴在偏房一處隱蔽的房頂上張望战虏。 院中可真熱鬧拣宰,春花似錦、人聲如沸烦感。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)手趣。三九已至晌该,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绿渣,已是汗流浹背朝群。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留中符,地道東北人姜胖。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像淀散,于是被迫代替她去往敵國(guó)和親右莱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容