數據集
最近別人給了我一個生物數據分割的標注數據集,讓我訓練一下,發現這個數據集比較詭異,圖像格式是tif的16位的浮點數,OpenCV讀取過來要顯示得先轉換,然后它的Mask是PNG的帶透明通道,最坑人的是Mask標記都是1、只有相互連接的對象標記才相互不同。官方給出的原始圖像解析以后是這樣:
OpenCV讀取顯示圖像樣本
OpenCV讀取tif格式16位的圖像在于imread的第二個參數,默認情況下會轉換為BGR彩色八位字節的圖像,如果這樣就是一片漆黑;這里選擇為-1表示不改變原圖像的通道數據信息,這樣就可以讀取原始圖像數據了,然后轉換為32f的,再歸一化到0~1之間,直接顯示即可。代碼如下:
importnumpyasnp img=cv.imread("D:/11111.tif",-1)#uint16 img_16=img.astype(np.float32) cv.normalize(img_16,img_16,0,1,cv.NORM_MINMAX) img_16.astype(np.float32) result=np.uint8(img_16*255) cv.imwrite('D:/tensor_cv2.jpg',result)
OpenCV讀取顯示Mask圖像
Mask圖像是帶透明通道的RGBA的圖像,但是實際上所有的標注信息只存在于red通道中,所以讀取以后,直接拆分通道,然后把red通道數據作為灰度圖像處理,因為灰度值太低了,顯示的時候我給擴大了點倍數,直接把灰度圖像扔到聯通組件掃描的函數中,然后就可以看到結果了。相關代碼如下:
importnumpyasnp img=cv.imread("D:/11111.png")#uint16 bb,gg,rr=cv.split(img) h,w,c=img.shape print(img.shape,img.dtype) numOfcons,labels=cv.connectedComponents(rr) colors=[] foriinrange(numOfcons): b=np.random.randint(0,256) g=np.random.randint(0,256) r=np.random.randint(0,256) colors.append((b,g,r)) colors[0]=(0,0,0) image=np.zeros((h,w,3),dtype=np.uint8) forrowinrange(h): forcolinrange(w): image[row,col]=colors[labels[row,col]] cv.imshow("coloredlabels",image) cv.imwrite("D:/opencv_labels.png",image) cv.imshow("bgr",rr*100) cv.waitKey(0) cv.destroyAllWindows()
標記的Mask信息原圖
基于聯通組件查找以后的彩色顯示(注意白色粘連)
對比與解決
對比之后發現,OpenCV中聯通組件掃描以后把不同標簽的樣本粘連在一起了,這個是因為OpenCV尋找聯通組件只分為兩種值0為背景,非0就作為前景,不做灰度級別區分的聯通域識別,所以導致了粘連。這個時候,只要用skimage庫的函數來替換OpenCV的聯通組件掃描就可以避免粘連了,因為skimage庫的聯通組件掃描支持獨立標簽分級。代碼演示如下:
importskimage.io importskimage.morphology #Loadoneimageafteruncompressingmasks.zip gt=skimage.io.imread("D:/11111.png") #Keepfirstchannelonly gt=gt[:,:,0] #Labelindependentconnectedcomponents gt=skimage.morphology.label(gt) colors=[] foriinrange(150): b=np.random.randint(0,256) g=np.random.randint(0,256) r=np.random.randint(0,256) colors.append((b,g,r)) colors[0]=(0,0,0) h,w=gt.shape image=np.zeros((h,w,3),dtype=np.uint8) forrowinrange(h): forcolinrange(w): image[row,col]=colors[gt[row,col]] #Displayimageoruseasneeded cv.imshow("coloredlabels",image) cv.imwrite("D:/labels.png",image) cv.waitKey(0) cv.destroyAllWindows()運行結果對比 - 可以發現白色區域沒有粘連,成功分割!
希望OpenCV遲早有一天可以支持這種分級的區域聯通組件掃描算法。
審核編輯:劉清
-
圖像處理
+關注
關注
27文章
1295瀏覽量
56813 -
OpenCV
+關注
關注
31文章
635瀏覽量
41399
原文標題:新知 | OpenCV4中聯通組件分析的一個缺點
文章出處:【微信號:CVSCHOOL,微信公眾號:OpenCV學堂】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論