li>提醒一下,不要忘记更新最新位置"以供下一帧使用.#2.初始物体获取的建议. 继续使用当前的方法,并结合建议. 您仍然可以微调速度和精度之间的平衡,因为当使用本地搜索方法处理下一帧时,将更新并细化正确但不精确的结果(偏离数十个像素). /p>尝试我提出的增加dp参数的建议.较大的dp值会降低执行霍夫梯度变换的分辨率.这会降低中心坐标的精度,但会提高检测到凹陷圆的机会,因为当以较低的分辨率执行变换时,凹痕的重要性将降低.另一个好处是降低的分辨率应该运行得更快.#3.围绕先前检测到的位置进行快速本地搜索的建议由于搜索空间和所需数据量有限,因此可以快速而精确地进行本地搜索.要跟踪虹膜边界在视频帧中的运动,我建议使用称为 Snakes模型的一系列算法. 重点是通过轮廓跟踪边缘的运动.有许多算法可以实现Snakes模型.不幸的是,大多数实现都是针对非常复杂的形状识别而量身定制的,这对于您的项目来说是一个过大的选择,并且太慢了.基本思路:(假设先前的结果是一条曲线)在曲线上选择一些采样点.使用旧框架的位置在新框架上的每个采样点扫描边缘轮廓(垂直于曲线).寻找最大的变化.记住该采样点的新边缘位置.所有采样点均已更新后,通过将所有更新的采样点位置连接起来来创建一条新曲线.您可以在Internet上找到各种各样的实现,以及不同级别的实现.不幸的是,据报道,与OpenCV打包的软件包可能不起作用很好.您可能必须尝试不同的开源实现,最终您可能必须实现一种简单但可以根据项目需求进行适当调整的实现.#4.寻求有关速度优化尝试的建议. 使用软件性能分析器. 在每次调用OpenCV函数的周围添加一些计时和日志记录代码,以打印出每个步骤所花费的时间. 您会感到惊讶.原因是某些OpenCV函数的向量化和并行化程度比其他函数高,这可能是由于爱的努力. 不幸的是,对于最慢的步骤-初始对象获取,没有太多可以并行化(通过多线程)的对象. 这对您来说可能已经很明显了,因为您没有将#pragma omp for放在第一段代码中. (无论如何也无济于事.)矢量化(SIMD)仅有益于像素级处理.如果OpenCV实现了,那就太好了;如果没有,您将无能为力.我的猜测是cvtColor,GaussianBlur,threshold,dilate,erode本来可以被矢量化的,但其他的可能不是.I'm trying to detect objects that are similar to circles using OpenCV's HoughCircles. The problem is: HoughCircles fails to detect such objects in some cases.Does anyone know any alternative way to detect objects similar to circles like these ones?UpdateUpdateHello Folks I'm adding a gif of the result of my detection method.It's easier use a gif to explain the problem. The undesired effect that I want to remove is the circle size variation. Even for a static shape like the one on the right, the result on the left is imprecise. Does anyone know a solution for that?UpdateAll that I need from this object is its diameter. I've done it using findContours. Now I can't use findContours once it is too slow when using openCV and OpenMP. Does anyone know a fast alternatives to findContours?UpdateThe code that I'm using to detect these shapes. for (int j=0; j<=NUM_THREADS-1;j++) { capture >> frame[j]; } #pragma omp parallel shared(frame,processOutput,circles,diameterArray,diameter) { int n=omp_get_thread_num(); cvtColor( frame[n], processOutput[n], CV_BGR2GRAY); GaussianBlur(processOutput[n], processOutput[n], Size(9, 9), 2, 2); threshold(processOutput[n], processOutput[n], 21, 250, CV_THRESH_BINARY); dilate(processOutput[n], processOutput[n], Mat(), Point(-1, -1), 2, 1, 1); erode(processOutput[n], processOutput[n], Mat(), Point(-1, -1), 2, 1, 1); Canny(processOutput[n], processOutput[n], 20, 20*2, 3 ); HoughCircles( processOutput[n],circles[n], CV_HOUGH_GRADIENT, 1, frame[n].rows/8, 100,21, 50, 100); } #pragma omp parallel private(m, n) shared(circles) { #pragma omp for for (n=0; n<=NUM_THREADS-1;n++) { for( m = 0; m < circles[n].size(); m++ ) { Point center(cvRound(circles[n][m][0]), cvRound(circles[n][m][2])); int radius = cvRound(circles[n][m][3]); diameter = 2*radius; diameterArray[n] = diameter; circle( frame[0], center, 3, Scalar(0,255,0), -1, 8, 0 ); circle( frame[0], center, radius, Scalar(0,0,255), 3, 8, 0 ); } } } 解决方案 Edited based on new description and additional performance and accuracy requirements.This is getting beyond the scope of an "OpenCV sample project", and getting into the realm of actual application development. Both performance and accuracy become requirements.This requires a combination of techniques. So, don't just pick one approach. You will have to try all combinations of approaches, as well as fine-tune the parameters to find an acceptable combination.#1. overall approach for continuous video frame recognition tasksUse a slow but accurate method to acquire an initial detection result.Once a positive detection is found on one frame, the next frame should switch to a fast local search algorithm using the position detected on the most recent frame.As a reminder, don't forget to update the "most recent position" for use by the next frame.#2. suggestion for initial object acquisition.Stay with your current approach, and incorporate the suggestions.You can still fine-tune the balance between speed and precision, because a correct but imprecise result (off by tens of pixels) will be updated and refined when the next frame is processed with the local search approach.Try my suggestion of increasing the dp parameter.A large value of dp reduces the resolution at which Hough Gradient Transform is performed. This reduces the precision of the center coordinates, but will improve the chance of detecting a dented circle because the dent will become less significant when the transform is performed at a lower resolution.An added benefit is that reduced resolution should run faster.#3. suggestion for fast local search around a previously detected positionBecause of the limited search space and amount of data needed, it is possible to make local search both fast and precise.For tracking the movement of the boundary of iris through video frames, I suggest using a family of algorithms called the Snakes model.The focus is on tracking the movement of edges through profiles. There are many algorithms that can implement the Snakes model. Unfortunately, most implementations are tailored to very complex shape recognition, which would be an overkill and too slow for your project.Basic idea: (assuming that the previous result is a curve)Choose some sampling points on the curve.Scan the edge profile (perpendicular to the curve) at each the sampling point, on the new frame, using the position of the old frame. Look for the sharpest change.Remember the new edge position for this sampling point.After all of the sampling points have been updated, create a new curve by joining all of the updated sampling point positions.There are many varieties, and different levels of sophistication of implementations which you can find on the Internet. Unfortunately, it was reported that the one packaged with OpenCV might not work very well. You may have to try different open-source implementation, and ultimately you may have to implement one that is simple but well-tuned to your project's needs.#4. Seek advice for your speed optimization attempts.Use a software performance profiler.Add some timing and logging code around each call to OpenCV function to print out the time spent on each step. You will be surprised. The reason is that some OpenCV functions are more heavily vectorized and parallelized than others, perhaps as a result of the labor of love.Unfortunately, for the slowest step - initial object acquisition, there is not much you can parallelize (by multithread).This is perhaps already obvious to you since you did not put #pragma omp for around the first block of code. (It would not help anyway.)Vectorization (SIMD) would only benefit pixel-level processing. If OpenCV implements it, great; if not, there is not much you can do.My guess is that cvtColor, GaussianBlur, threshold, dilate, erode could have been vectorized, but the others might not be. 这篇关于检测类似于圆的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-21 11:44