圆形霍夫变换的改进
我正在研究一种虹膜识别算法,该算法将这些类型的图像处理成唯一的代码以进行识别和身份验证目的。
在过滤、智能阈值处理、然后找到图像中的边缘之后,下一步显然是为瞳孔和虹膜拟合圆圈。我环顾四周,使用的技术是圆形霍夫变换。这是我的实现代码。抱歉,变量名称很神秘。
print "Populating Accumulator..."
# Loop over image rows
for x in range(w):
# Loop over image columns
for y in range(h):
# Only process black pixels
if inp[x,y] == 0:
# px,py = 0 means pupil, otherwise pupil center
if px == 0:
ra = r_min
rb = r_max
else:
rr = sqrt((px-x)*(px-x)+(py-y)*(py-y))
ra = int(rr-3)
rb = int(rr+3)
# a is the width of the image, b is the height
for _a in range(a):
for _b in range(b):
for _r in range(rb-ra):
s1 = x - (_a + a_min)
s2 = y - (_b + b_min)
r1 = _r + ra
if (s1 * s1 + s2 * s2 == r1 * r1):
new = acc[_a][_b][_r]
if new >= maxVotes:
maxVotes = new
print "Done"
# Average all circles with the most votes
for _a in range(a):
for _b in range(b):
for _r in range(r):
if acc[_a][_b][_r] >= maxVotes-1:
total_a += _a + a_min
total_b += _b + b_min
total_r += _r + r_min
amount += 1
top_a = total_a / amount
top_b = total_b / amount
top_r = total_r / amount
print top_a,top_b,top_r
这是用Python编写的,并使用Python Imaging Library来进行图像处理。正如您所看到的,这是一种非常简单的寻找圆的蛮力方法。它有效,但需要几分钟。基本思想是在有黑色像素的地方(来自阈值和边缘检测)绘制从 rmin 到 rmax 的圆圈,构建一个累加器数组,其中包含图像上某个位置被“投票”的次数。 x、y、r 中得票最多的就是兴趣圈。我尝试利用虹膜和瞳孔具有大致相同的中心(变量 ra 和 rb)这一事实来降低 r 循环的一些复杂性,但瞳孔检测花费的时间太长,因此并不重要。
现在,显然我的实现非常幼稚。它使用三维参数空间(x、y 和 r),不幸的是,这使其运行速度低于可接受的速度。我可以做出哪些改进?有什么办法可以将其简化为二维参数空间吗?是否有更有效的方法来访问和设置我不知道的像素?
顺便说一句,是否还有其他我不知道的技术可以提高该算法的整体运行时间?例如近似瞳孔或虹膜最大半径的方法?
注意:我也尝试使用 OpenCV 来实现此目的,但我无法将参数调整到足以保持一致的准确度。
如果您需要任何其他信息,请告诉我。
注意:我再次误解了我自己的代码。从技术上讲,它是 5 维的,但 3 维 x,y,r 循环仅对黑色像素进行操作。
I'm working on an iris recognition algorithm that processes these kind of images into unique codes for identification and authentication purposes.
After filtering, intelligently thresholding, then finding edges in the image, the next step is obviously to fit circles to the pupil and iris. I've looked around the the technique to use is the circular Hough Transform. Here is the code for my implementation. Sorry about the cryptic variable names.
print "Populating Accumulator..."
# Loop over image rows
for x in range(w):
# Loop over image columns
for y in range(h):
# Only process black pixels
if inp[x,y] == 0:
# px,py = 0 means pupil, otherwise pupil center
if px == 0:
ra = r_min
rb = r_max
else:
rr = sqrt((px-x)*(px-x)+(py-y)*(py-y))
ra = int(rr-3)
rb = int(rr+3)
# a is the width of the image, b is the height
for _a in range(a):
for _b in range(b):
for _r in range(rb-ra):
s1 = x - (_a + a_min)
s2 = y - (_b + b_min)
r1 = _r + ra
if (s1 * s1 + s2 * s2 == r1 * r1):
new = acc[_a][_b][_r]
if new >= maxVotes:
maxVotes = new
print "Done"
# Average all circles with the most votes
for _a in range(a):
for _b in range(b):
for _r in range(r):
if acc[_a][_b][_r] >= maxVotes-1:
total_a += _a + a_min
total_b += _b + b_min
total_r += _r + r_min
amount += 1
top_a = total_a / amount
top_b = total_b / amount
top_r = total_r / amount
print top_a,top_b,top_r
This is written in python and uses the Python Imaging Library to do image processing. As you can see, this is a very naive brute force method of finding circles. It works, but takes several minutes. The basic idea is to draw circles from rmin to rmax wherever there is a black pixel (from thresholding and edge-detection), the build an accumulator array of the number of times a location on the image is "voted" on. Whichever x, y, and r has the most votes is the circle of interest. I tried to use the fact that the iris and pupil have about the same center (variables ra and rb) to reduce some of the complexity of the r loop, but the pupil detection takes so long that it doesn't matter.
Now, obviously my implementation is very naive. It uses a three dimensional parameter space (x, y, and r), which unfortunately makes it run slower than is acceptable. What kind of improvements can I make? Is there any way to reduce this to a two-dimensional parameter space? Is there a more efficient way of accessing and setting pixels that I'm not aware of?
On a side note, are there any other techniques for improving the overall runtime of this algorithm that I'm not aware of? Such as methods to approximate the maximum radius of the pupil or iris?
Note: I've tried to use OpenCV for this as well, but I could not tune the parameters enough to be consistently accurate.
Let me know if there's any other information that you need.
NOTE: Once again I misinterpreted my own code. It is technically 5-dimensional, but the 3-dimensional x,y,r loop only operates on black pixels.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
假设您想要的是圆的位置而不是 R 的测量值。
如果您对 R 的可能范围有一个不错的估计,那么常见的技术是运行算法来首次猜测固定 R,调整它并重试。
Assuming you want the position of the circle rather than a measure of R.
If you have a decent estimate of the possible range of R then a common technique is to run the algorithm for a first guess of fixed R, adjust it and try again.