python_opencv实现图像分割(多分类彩色图像)孔洞填充后处理

我们在进行图像分割后,分割图像结果有时会有一些小孔洞,如下图所示。今天我们就用python语言基于OpenCV实现孔洞填充。
python_opencv实现图像分割(多分类彩色图像)孔洞填充后处理_第1张图片
代码实现:

import cv2;
import numpy as np;

def FillHole_RGB(imgPath,SavePath):
    # 读取图像为uint32,之所以选择uint32是因为下面转为0xbbggrr不溢出
    im_in_rgb = cv2.imread(imgPath).astype(np.uint32)
    
    # 将im_in_rgb的RGB颜色转换为 0xbbggrr
    im_in_lbl = im_in_rgb[:,:,0] + (im_in_rgb[:,:,1] << 8) + (im_in_rgb[:,:,2] << 16)
    
    # 将0xbbggrr颜色转换为0,1,2,...
    colors, im_in_lbl_new = np.unique(im_in_lbl, return_inverse=True)

    # 将im_in_lbl_new数组reshape为2维
    im_in_lbl_new = np.reshape(im_in_lbl_new,im_in_lbl.shape)
    
    # 创建从32位im_in_lbl_new到8位colorize颜色的映射
    colorize = np.empty((len(colors), 3), np.uint8)
    colorize[:,0] = (colors & 0x0000FF)
    colorize[:,1] = (colors & 0x00FF00) >> 8
    colorize[:,2] = (colors & 0xFF0000) >> 16
    
    # 输出一下colorize中的color
    print("Colors_RGB: \n",colorize)
    
    # 有几种颜色就设置几层数组,每层数组均为各种颜色的二值化数组
    im_result = np.zeros((len(colors),)+im_in_lbl_new.shape,np.uint8)
    
    # 初始化二值数组
    im_th = np.zeros(im_in_lbl_new.shape,np.uint8)
    
    for i in range(len(colors)):
        for j in range(im_th.shape[0]):
            for k in range(im_th.shape[1]):
                if(im_in_lbl_new[j][k]==i):
                    im_th[j][k] = 255
                else:
                    im_th[j][k] = 0
        # 复制 im_in 图像
        im_floodfill = im_th.copy()
     
        # Mask 用于 floodFill,官方要求长宽+2.
        h, w = im_th.shape[:2]
        mask = np.zeros((h+2, w+2), np.uint8)
        
        isbreak = False
        for m in range(im_floodfill.shape[0]):
            for n in range(im_floodfill.shape[1]):
                if(im_floodfill[m][n]==0):
                    seedPoint=(m,n)
                    isbreak = True
                    break
            if(isbreak):
                break
                
        # 得到im_floodfill
        cv2.floodFill(im_floodfill, mask, seedPoint, 255);
         
        # 得到im_floodfill的逆im_floodfill_inv
        im_floodfill_inv = cv2.bitwise_not(im_floodfill)
         
        # 把im_in、im_floodfill_inv这两幅图像结合起来得到前景
        im_out = im_th | im_floodfill_inv
        im_result[i] = im_out
    
    # rgb结果图像
    im_fillhole = np.zeros((im_in_lbl_new.shape[0],im_in_lbl_new.shape[1],3),np.uint8)
    
    # 之前的颜色映射起到了作用
    for i in range(im_result.shape[1]):
        for j in range(im_result.shape[2]):
            for k in range(im_result.shape[0]):
                if(im_result[k][i][j] == 255):
                    im_fillhole[i][j] = colorize[k]
                    break
    
    # 保存图像
    cv2.imwrite(SavePath, im_fillhole)

孔洞填充结果如下:
python_opencv实现图像分割(多分类彩色图像)孔洞填充后处理_第2张图片

你可能感兴趣的:(图像后处理,OpenCV,OpenCV,孔洞填充)