图像的异或操作和寻找图像局部最大值

首先介绍图像的异或操作,其可以用八个字概括:相同为假,相异为真。
如下:

A=array([[ True,  True,  True],
       [ True,  **False**,  True],
       [ True,  True,  True]], dtype=bool)
B=array([[ True,  True,  True],
       [ True,  **True**,  True],
       [ True,  True,  True]], dtype=bool)
A^B=array([[False, False, False],
       [False, **True**, False],
       [False, False, False]], dtype=bool)

在找图像局部最大值的时候,可分为以下几步:
1、 对图像进行最大值滤波(scipy 中的函数有最大值滤波函数),然后使得其等于原图,其得到一个bool 类型的矩阵。此时,最大值邻域都是True—-local_maxinum
2、 要想得到peaks,还得从以上操作中移除图像背景,即是利用异或操作,background^ local_maxinum
3、 对于2中的结果,寻找其等于True的列与行就是对应的局部最大值坐标
例子如下—齿轮定位:
本打算采用找轮廓算法来确定每个零件的中心和半径,但是由于零件之间由重叠,找轮廓效果见下图
这里写图片描述
所以笔者采用的方法是
1、 二值化(注意反转,齿轮式黑色)

def process_img(img):
    if img.ndim==3:
        img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    img=cv2.medianBlur(img,3)
    _,thresh=cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    return thresh

2、 填洞,注意的是cv2.floodFill()这个mask 的宽高等于binary image 宽高加2

def fillhole(thresh):
    h,w=thresh.shape[:]
    mask=np.zeros((h+2,w+2),np.uint8)
    holes=cv2.floodFill(thresh.copy(),mask,(0,0),255)
    s=cv2.bitwise_not(holes[1])
    full_thresh=s|thresh
    return full_thresh

这里写图片描述

3、 距离变换,也成EDM(距离映射),是指每个像素到背景像素的距离,越亮的地方离背景像素越远。距离变换有很多应用,如骨架提取,半径提取等。

distance=cv2.distanceTransform(full_threshh,2,5)

4、 寻找局部最大值,笔者的找局部最大不稳定

def detect_peaks(img):#2d local maxinum
    neighborhood=generate_binary_structure(2,2)
    local_peaks=maximum_filter(img,footprint=neighborhood)==img
    ## 此时,local_peaks是bool值,False代表局部最大值
    ##但由于背景的存在,必须从local_peaks移除背景
    background=(img==0)
    erode_background=binary_erosion(background,structure=neighborhood,border_value=1)
    peaks=local_peaks^erode_background
    return peaks

5、 笔者找到局部最大指后(cols,rows),用半径过滤,其半径就是对应距离变换后的值

    peaks=detect_peaks(distance)
    cols_and_rows=[[j,i] for i,j in zip(*np.where(peaks==True))]
    #判断半径
    true_pos=[]
    for t in cols_and_rows:
        if distance[t[1],t[0]]>50:
            true_pos.append(t)
            cv2.putText(im,"pos=(%g,%g),r=%g"%(t[0],t[1],distance[t[1],t[0]]),(t[0],t[1]),cv2.FONT_HERSHEY_SIMPLEX,0.5,[0,0,255],2)

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_15642411/article/details/80486208