编写健壮(颜色和尺寸不变)圆检测用的OpenCV(基于Hough变换或其他特征) [英] writing robust (color and size invariant) circle detection with opencv (based on Hough transform or other features)

查看:448
本文介绍了编写健壮(颜色和尺寸不变)圆检测用的OpenCV(基于Hough变换或其他特征)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了下面非常简单的Python code找到图像中界:

I wrote the following very simple python code to find circles in an image:

import cv
import numpy as np

WAITKEY_DELAY_MS = 10
STOP_KEY = 'q'

cv.NamedWindow("image - press 'q' to quit", cv.CV_WINDOW_AUTOSIZE);
cv.NamedWindow("post-process", cv.CV_WINDOW_AUTOSIZE);

key_pressed = False
while key_pressed != STOP_KEY:

    # grab image
    orig = cv.LoadImage('circles3.jpg')

    # create tmp images
    grey_scale = cv.CreateImage(cv.GetSize(orig), 8, 1)
    processed = cv.CreateImage(cv.GetSize(orig), 8, 1)


    cv.Smooth(orig, orig, cv.CV_GAUSSIAN, 3, 3)

    cv.CvtColor(orig, grey_scale, cv.CV_RGB2GRAY)

    # do some processing on the grey scale image
    cv.Erode(grey_scale, processed, None, 10)
    cv.Dilate(processed, processed, None, 10)
    cv.Canny(processed, processed, 5, 70, 3)
    cv.Smooth(processed, processed, cv.CV_GAUSSIAN, 15, 15)

    storage = cv.CreateMat(orig.width, 1, cv.CV_32FC3)

    # these parameters need to be adjusted for every single image
    HIGH = 50
    LOW = 140

    try: 
        # extract circles
        cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 32.0, HIGH, LOW)

        for i in range(0, len(np.asarray(storage))):
            print "circle #%d" %i
            Radius = int(np.asarray(storage)[i][0][2])
            x = int(np.asarray(storage)[i][0][0])
            y = int(np.asarray(storage)[i][0][1])
            center = (x, y)

            # green dot on center and red circle around
            cv.Circle(orig, center, 1, cv.CV_RGB(0, 255, 0), -1, 8, 0)
            cv.Circle(orig, center, Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0)

            cv.Circle(processed, center, 1, cv.CV_RGB(0, 255, 0), -1, 8, 0)
            cv.Circle(processed, center, Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0)

    except:
        print "nothing found"
        pass

    # show images
    cv.ShowImage("image - press 'q' to quit", orig)
    cv.ShowImage("post-process", processed)

    cv_key = cv.WaitKey(WAITKEY_DELAY_MS)
    key_pressed = chr(cv_key & 255)

你可以从下面的两个例子看到,圈子发现质量变化颇多:

As you can see from the following two examples, the 'circle finding quality' varies quite a lot:

CASE1:



CASE2:



案例1和第2种情况基本上是相同的图像,但仍是算法检测不同的圈子。如果我present的算法不同大小的圆形图像时,圆检测甚至可能完全失败。这主要是由于它需要为每个新画面进行单独调整 HIGH LOW 参数。

Case1 and Case2 are basically the same image, but still the algorithm detects different circles. If I present the algorithm an image with differently sized circles, the circle detection might even fail completely. This is mostly due to the HIGH and LOW parameters which need to be adjusted individually for each new picture.

所以我的问题:什么是使这个算法更加健壮的各种可能性?以便检测不同圆用不同的颜色和不同的尺寸应该是大小和颜色不变。也许使用霍夫变换是不是做事情的最好方法?有没有更好的办法?

Therefore my question: what are the various possibilities of making this algorithm more robust? It should be size and color invariant so that different circles with different colors and in different sizes are detected. Maybe using the Hough transform is not the best way of doing things? Are there better approaches?

推荐答案

是基于我作为一个视觉研究者体验下。从你的问题,你似乎是有意可能的算法和方法,而只有一个工作片code的。首先我给一个快速和肮脏的Python脚本为您的样本图像和一些结果显示,以证明它可能解决您的问题。获得这些闪开后,我试着回答你关于稳健的检测算法的问题。

The following is based on my experience as a vision researcher. From your question you seem to be interested in possible algorithms and methods rather only a working piece of code. First I give a quick and dirty Python script for your sample images and some results are shown to prove it could possibly solve your problem. After getting these out of the way, I try to answer your questions regarding robust detection algorithms.

一些样本图像(除了你是从flickr.com下载并CC许可的所有图像)与被检测圆(不改变/调整任何参数,严格按照下列code被用于提取圈子里所有的图像):



Some sample images (all the images apart from yours are downloaded from flickr.com and are CC licensed) with the detected circles (without changing/tuning any parameters, exactly the following code is used to extract the circles in all the images):

这里是code:

import cv2
import math
import numpy as np

d_red = cv2.cv.RGB(150, 55, 65)
l_red = cv2.cv.RGB(250, 200, 200)

orig = cv2.imread("c.jpg")
img = orig.copy()
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

detector = cv2.FeatureDetector_create('MSER')
fs = detector.detect(img2)
fs.sort(key = lambda x: -x.size)

def supress(x):
        for f in fs:
                distx = f.pt[0] - x.pt[0]
                disty = f.pt[1] - x.pt[1]
                dist = math.sqrt(distx*distx + disty*disty)
                if (f.size > x.size) and (dist<f.size/2):
                        return True

sfs = [x for x in fs if not supress(x)]

for f in sfs:
        cv2.circle(img, (int(f.pt[0]), int(f.pt[1])), int(f.size/2), d_red, 2, cv2.CV_AA)
        cv2.circle(img, (int(f.pt[0]), int(f.pt[1])), int(f.size/2), l_red, 1, cv2.CV_AA)

h, w = orig.shape[:2]
vis = np.zeros((h, w*2+5), np.uint8)
vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)
vis[:h, :w] = orig
vis[:h, w+5:w*2+5] = img

cv2.imshow("image", vis)
cv2.imwrite("c_o.jpg", vis)
cv2.waitKey()
cv2.destroyAllWindows()

正如你可以看到它的基础上, MSER 一滴探测器。在code没有preprocess图像除了简单的映射成灰度。因此缺少图像的淡黄色斑点的预期。

As you can see it's based on the MSER blob detector. The code doesn't preprocess the image apart from the simple mapping into grayscale. Thus missing those faint yellow blobs in your images is expected.

简而言之:你不告诉我们你从没有对它们的描述给只有两个样本图像所知道的问题分开。在这里,我解释了为什么我在我的愚见,询问有什么有效的方法来攻击这个问题之前,有关于该问题的更多信息是非常重要的。

回到主要问题:什么是这个问题的最好方法是什么?
让我们来看看这是一个搜索问题。为了简化讨论假设我们正在寻找一个给定的尺寸/半径的圆。因此,问题归结为寻找中心。每个像素是候选中心,因此,在搜索空间中包含的所有像素。

Back to the main question: what is the best method for this problem? Let's look at this as a search problem. To simplify the discussion assume we are looking for circles with a given size/radius. Thus, the problem boils down to finding the centers. Every pixel is a candidate center, therefore, the search space contains all the pixels.

P = {p1, ..., pn} 
P: search space
p1...pn: pixels

要解决这个问题,搜索其他两个功能应该被定义:

To solve this search problem two other functions should be defined:

E(P) : enumerates the search space
V(p) : checks whether the item/pixel has the desirable properties, the items passing the check are added to the output list

假设该算法并不重要的复杂性,详尽的或穷举搜索可以使用其中E取的每个像素,并传递到V.在实时应用来减少搜索空间并优化计算是非常重要的五,效率

Assuming the complexity of the algorithm doesn't matter, the exhaustive or brute-force search can be used in which E takes every pixel and passes to V. In real-time applications it's important to reduce the search space and optimize computational efficiency of V.

我们正在接近的主要问题。我们可以如何界定V,更precise哪些候选人性能应措施和如何使解决这些问题分割成可取和不可取的二分法问题。最常用的方法是找到一些性质,可用于定义基于属性的测量简单的决策规则。这就是你通过试验和错误做什么。你从正面和反面的例子学习编程的分类。这是因为你使用的方法不知道你想做什么。你必须调整决策规则和/或preprocess的/调的参数中的数据,使得在属性(所希望的候选)通过为二分法问题的方法中使用的变化被降低。可以使用机器学习算法来找到最优的参数值对于一个给定的实施例。还有从决策树遗传程序,您可以使用此问题的学习算法一大堆。你也可以使用一个学习算法来找到最优的参数值几个圈检测算法,看看哪一个给出更好的精度。这发生在你只需要收集样本图像的学习算法的主要负担。

We are getting closer to the main question. How we could define V, to be more precise what properties of the candidates should be measures and how should make solve the dichotomy problem of splitting them into desirable and undesirable. The most common approach is to find some properties which can be used to define simple decision rules based on the measurement of the properties. This is what you're doing by trial and error. You're programming a classifier by learning from positive and negative examples. This is because the methods you're using have no idea what you want to do. You have to adjust / tune the parameters of the decision rule and/or preprocess the data such that the variation in the properties (of the desirable candidates) used by the method for the dichotomy problem are reduced. You could use a machine learning algorithm to find the optimal parameter values for a given set of examples. There's a whole host of learning algorithms from decision trees to genetic programming you can use for this problem. You could also use a learning algorithm to find the optimal parameter values for several circle detection algorithms and see which one gives a better accuracy. This takes the main burden on the learning algorithm you just need to collect sample images.

另一种方法来提高稳健性经常被忽视是利用额外的现成资料。如果知道圆的几乎零额外的努力的颜色可以显著改进该检测器的准确性。如果你知道圆的平面上的位置,你想检测成像圈,你应该记住是由2D单应说明这两套位置之间的转换。而且该单对应性可以仅使用四个点来估计。然后,你可以提高稳健性有一个坚如磐石的方法。的特定领域的知识的价值往往被低估。看看这样的方式,在第一种方法,我们尝试近似基于样本数量有限的一些决策规则。在第二种方法我们知道决策规则,只需要找到一种方法来有效地利用他们的算法。

The other approach to improve robustness which is often overlooked is to utilize extra readily available information. If you know the color of the circles with virtually zero extra effort you could improve the accuracy of the detector significantly. If you knew the position of the circles on the plane and you wanted to detect the imaged circles, you should remember the transformation between these two sets of positions is described by a 2D homography. And the homography can be estimated using only four points. Then you could improve the robustness to have a rock solid method. The value of domain-specific knowledge is often underestimated. Look at it this way, in the first approach we try to approximate some decision rules based on a limited number of sample. In the second approach we know the decision rules and only need to find a way to effectively utilize them in an algorithm.

要总结,有以提高溶液的准确度/鲁棒两种方法:

To summarize, there are two approaches to improve the accuracy / robustness of the solution:


  1. 工具为主:寻找一个更容易使用的算法/用较少数量的参数/调整算法/使用机器学习算法自动完成这个过程

  2. 信息化:您正在使用的所有现成的资料?在这个问题你不提你知道什么问题。

  1. Tool-based: finding an easier to use algorithm / with fewer number of parameters / tweaking the algorithm / automating this process by using machine learning algorithms
  2. Information-based: are you using all the readily available information? In the question you don't mention what you know about the problem.

有关你分享我会用一个blob检测不是HT法这两个图像。背景扣除我建议尝试估计背景的颜色作为它不改变,而圆的颜色变化的两个图像。而大部分区域是光秃秃的。

For these two images you have shared I would use a blob detector not the HT method. For background subtraction I would suggest to try to estimate the color of the background as in the two images it is not varying while the color of the circles vary. And the most of the area is bare.

这篇关于编写健壮(颜色和尺寸不变)圆检测用的OpenCV(基于Hough变换或其他特征)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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