图像处理-消除弧形污迹 [英] Image processing - eliminate arc-like smears

查看:92
本文介绍了图像处理-消除弧形污迹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理这种图像



(上部经过后处理)



(下面是原始数据)
因此,首先我将灰度图像转换为纯黑白二进制图像。我有兴趣检测白色斑点,并希望消除角落中的弧形涂抹。我该怎么做?



我一般来说,我知道我的目标几乎是圆形的,不是太大,但是我想编码一些可以自动去除的东西



如何在 python 中执行此操作,最好是 skimage

解决方案

您可以检测到右侧的圆大小和skimage的方法 hough_circle hough_circle_peaks 并切掉。



在这里,我将



再次,就像我之前的回答一样,这里的大多数代码都在进行层次结构计算,以找到最大的最佳拟合圆。


I am dealing with this kind of image

(upper is post-processed)

(lower is raw) So, first I converted the grayscale image into pure black and white binary image. I am interested in detecting the white blobs, and want to get rid of the arc-like smears in the corners. How can I do that?

I general, I know that my targets are almost circular in shape, not too big, but I want to encode something that automatically gets rid of everything else, like the lighter arcs in the upper left and right corners.

How would I do this in python, ideally skimage?

解决方案

You can just detect circle of the right size with skimage's methods hough_circle and hough_circle_peaks and cut it out.

Here I adapted my previous answer to your other question to do this:

# skimage version 0.14.0

import math
import numpy as np
import matplotlib.pyplot as plt

from skimage import color
from skimage.io import imread
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle
from skimage.util import img_as_ubyte

INPUT_IMAGE = 'dish1.png' # input image name
BEST_COUNT = 1            # how many circles to detect (one dish)
MIN_RADIUS = 100          # min radius of the Petri dish
MAX_RADIUS = 122          # max radius of the Petri dish (in pixels)
LARGER_THRESH = 1.2       # circle is considered significantly larger than another one if its radius is at least so much bigger
OVERLAP_THRESH = 0.1      # circles are considered overlapping if this part of the smaller circle is overlapping

def circle_overlap_percent(centers_distance, radius1, radius2):
    '''
    Calculating the percentage area overlap between circles
    See Gist for comments:
        https://gist.github.com/amakukha/5019bfd4694304d85c617df0ca123854
    '''
    R, r = max(radius1, radius2), min(radius1, radius2)
    if centers_distance >= R + r:
        return 0.0
    elif R >= centers_distance + r:
        return 1.0
    R2, r2 = R**2, r**2
    x1 = (centers_distance**2 - R2 + r2 )/(2*centers_distance)
    x2 = abs(centers_distance - x1)
    y = math.sqrt(R2 - x1**2)
    a1 = R2 * math.atan2(y, x1) - x1*y
    if x1 <= centers_distance:
        a2 = r2 * math.atan2(y, x2) - x2*y
    else:
        a2 = math.pi * r2 - a2
    overlap_area = a1 + a2
    return overlap_area / (math.pi * r2)

def circle_overlap(c1, c2):
    d = math.sqrt((c1[0]-c2[0])**2 + (c1[1]-c2[1])**2)
    return circle_overlap_percent(d, c1[2], c2[2])

def inner_circle(cs, c, thresh):
    '''Is circle `c` is "inside" one of the `cs` circles?'''
    for dc in cs:
        # if new circle is larger than existing -> it's not inside
        if c[2] > dc[2]*LARGER_THRESH: continue
        # if new circle is smaller than existing one...
        if circle_overlap(dc, c)>thresh:
            # ...and there is a significant overlap -> it's inner circle
            return True
    return False

# Load picture and detect edges
image = imread(INPUT_IMAGE, 1)
image = img_as_ubyte(image)
edges = canny(image, sigma=3, low_threshold=10, high_threshold=50)

# Detect circles of specific radii
hough_radii = np.arange(MIN_RADIUS, MAX_RADIUS, 2)
hough_res = hough_circle(edges, hough_radii)

# Select the most prominent circles (in order from best to worst)
accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii)

# Determine BEST_COUNT circles to be drawn
drawn_circles = []
for crcl in zip(cy, cx, radii):
    # Do not draw circles if they are mostly inside better fitting ones
    if not inner_circle(drawn_circles, crcl, OVERLAP_THRESH):
        # A good circle found: exclude smaller circles it covers
        i = 0
        while i<len(drawn_circles):
            if circle_overlap(crcl, drawn_circles[i]) > OVERLAP_THRESH:
                t = drawn_circles.pop(i)
            else:
                i += 1
        # Remember the new circle
        drawn_circles.append(crcl)
    # Stop after have found more circles than needed
    if len(drawn_circles)>BEST_COUNT:
        break

drawn_circles = drawn_circles[:BEST_COUNT]

# Draw circle and cut it out
colors  = [(250, 0, 0), (0, 250, 0), (0, 0, 250)]
fig, ax = plt.subplots(ncols=1, nrows=3, figsize=(10, 4))
color_image = color.gray2rgb(image)
black_image = np.zeros_like(image)
for center_y, center_x, radius in drawn_circles[:1]:
    circy, circx = circle(center_y, center_x, radius, image.shape)
    color = colors.pop(0)
    color_image[circy, circx] = color
    black_image[circy, circx] = image[circy, circx]
    colors.append(color)

# Output
ax[0].imshow(image, cmap=plt.cm.gray)        # original image
ax[1].imshow(color_image)                    # detected circle
ax[2].imshow(black_image, cmap=plt.cm.gray)  # cutout
plt.show()

Output:

Again, as in my previous answer, most of the code here is doing "hierarchy" computation to find the biggest best fitting circle.

这篇关于图像处理-消除弧形污迹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆