霍夫变换检测圆

参考链接:https://github.com/mokosaur/iris-recognition

代码:

import matplotlib.pyplot as plt
import cv2
import math
import numpy as np
from scipy.ndimage.filters import gaussian_filter
import os
import time


def show_segment(save_name,img, x, y, r, x2=None, y2=None, r2=None):
    plt.subplots(1, 1)
    ax = plt.subplot()
    ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    # 画虹膜
    segment = plt.Circle((x, y), r, color='b', fill=False)
    ax.add_artist(segment)

    # # 画巩膜
    # if r2 is not None:
    #     segment2 = plt.Circle((x2, y2), r2, color='r', fill=False)
    #     ax.add_artist(segment2)

    plt.savefig(save_name)
    return plt

def integrate(img, x0, y0, r, arc_start=0, arc_end=1, n=8):
    theta = 2 * math.pi / n
    integral = 0
    for step in np.arange(arc_start * n, arc_end * n, arc_end - arc_start):
        x = int(x0 + r * math.cos(step * theta))
        y = int(y0 + r * math.sin(step * theta))
        integral += img[x, y]
    return integral / n

def find_segment(img, x0, y0, minr=0, maxr=500, step=1, sigma=5., center_margin=30, segment_type='iris', jump=1):
    max_o = 0
    max_l = []

    if img.ndim > 2:
        img = img[:, :, 0]
    margin_img = np.pad(img, maxr, 'edge')
    x0 += maxr
    y0 += maxr
    for x in range(x0 - center_margin, x0 + center_margin + 1, jump):
        for y in range(y0 - center_margin, y0 + center_margin + 1, jump):
            if segment_type == 'pupil':
                l = np.array([integrate(margin_img, y, x, r) for r in range(minr, maxr, step)])
            else:
                l = np.array([integrate(margin_img, y, x, r, 1 / 8, 3 / 8, n=8) +
                              integrate(margin_img, y, x, r, 5 / 8, 7 / 8, n=8)
                              for r in range(minr + abs(x0 - x) + abs(y0 - y), maxr, step)])
            l = (l[2:] - l[:-2]) / 2
            l = gaussian_filter(l, sigma)
            l = np.abs(l)
            max_c = np.max(l)
            if max_c > max_o:
                max_o = max_c
                max_l = l
                max_x, max_y = x, y
                r = np.argmax(l) * step + minr + abs(x0 - x) + abs(y0 - y)

    return max_x - maxr, max_y - maxr, r, max_l


def preprocess(image):
    img = image[:, :, 0].copy()
    img[img > 225] = 30
    return cv2.medianBlur(img, 21)


def find_pupil_hough(img):
    # circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20,
    #                            param1=50, param2=30, minRadius=10, maxRadius=200)
    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20,
                               param1=30, param2=30, minRadius=20, maxRadius=80)
    if circles is not None:
        circles = np.uint16(np.around(circles))
        return circles[0, 0][0], circles[0, 0][1], circles[0, 0][2]
    else:
        return 0,0,0


def find_iris_id(img, x, y, r):
    x, y, r, l = find_segment(img, x, y, minr=max(int(1.25 * r), 100),
                              sigma=5, center_margin=30, jump=5)
    x, y, r, l = find_segment(img, x, y, minr=r - 10, maxr=r + 10,
                              sigma=2, center_margin=5, jump=1)
    return x, y, r

def limit(a,g0=None,g1=None):
    if a<=0:
        b=0
    else:
        b=a

    if g1>=g0:
        gg=g0
    else:
        gg=g1
    return b,gg

def get_eye_roi(image,x, y, r,save_name2):
    # 左上角点
    x1,_=limit(int(x)-int(r),0,0)
    y1,_=limit(int(y)-int(r),0,0)

    # 需要裁剪的长宽
    w0=image.shape[1]
    h0=image.shape[0]

    h1=int(y1+2*r)
    w1=int(x1+2*r)
    _,w1=limit(0,w0,w1)
    _,h1=limit(0,h0,h1)

    img2=image[y1:h1,x1:w1]
    cv2.imwrite(save_name2,img2)


def white_num(image, x, y, r):
    a=[]
    b=[]
    n=0
    gray=cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
    for i in range(y-r,y):
        print(gray[i,x])
        a.append(x)
        b.append(i)

        if gray[i,x]>=180:
            n +=1
    
    plt.plot(a,b,linewidth = '2', label = file.split(".")[0], linestyle='-', marker=' ')    #画图
    plt.show()
    
    return n

# Example usage
if __name__ == '__main__':
    path = "img/1/"
    save = "img/"
    save2 = "img/"
    
    for file in os.listdir(path):
        file_name=path+file
        image = cv2.imread(file_name)
        
        img = preprocess(image)
        x, y, r = find_pupil_hough(img)
        print(file_name,r*2)

        # 画出虹膜区域
        save_name=save+file+".png"
        show_segment(save_name,image, x, y, r)
        
        # # 裁剪虹膜roi的外接圆
        # if r>=5:
        #       save_name2=save2+file
        #       get_eye_roi(image,x, y, r,save_name2)
               
        # # 计算白点的数量
        # n=white_num(image, x, y, r)
        # print("白点数量:",n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值