在 C++ 中计算图像骨架的最快方法
Posted
技术标签:
【中文标题】在 C++ 中计算图像骨架的最快方法【英文标题】:Fastest way to calculate skeleton of image in C++ 【发布时间】:2018-04-23 14:57:06 【问题描述】:我正在使用 OpenCV (C++) 并希望以最快的方式找到图像的骨架。
输入图像hand_bw
为:
到目前为止,这就是我所拥有的:
cv::Mat skel(hand_bw.size(), CV_8UC1, cv::Scalar(0));
cv::Mat temp(hand_bw.size(), CV_8UC1);
cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
bool done;
int i = 0;
do
cv::morphologyEx(hand_bw, temp, cv::MORPH_OPEN, element);
cv::bitwise_not(temp, temp);
cv::bitwise_and(hand_bw, temp, temp);
cv::bitwise_or(skel, temp, skel);
cv::erode(hand_bw, hand_bw, element);
double max;
cv::minMaxLoc(hand_bw, 0, &max);
done = (max == 0);
i = i+1;
while (!done);
cv::imshow("Skeleton", skel);
对应的输出是:
在 C++(可能是动态编程)中实现此结果的最快方法是什么?时间是我的主要限制。
【问题讨论】:
我从来没有遇到过不能更快的 C++ 程序。所以“是”。一般来说? “让它去”是一个糟糕的 SO 问题。 我不确定您如何使用它,但我几乎 100% 确定还有另一种 OpenCV 方法可以执行该操作。无论如何,您是否尝试过重构该代码以使用 OpenCV 的透明 API? 你能发布输出帧吗? 这是一个研究问题。有关于此的论文,尽管通常是针对 3D 场景的。研究“快速近似凸分解” @Meghana OpenCV 的透明 API 是一个非常易于使用的 API,它使昂贵的操作(如您的)能够使用硬件(如 GPU)使其更快。这是一个简单的教程:learnopencv.com/opencv-transparent-api 【参考方案1】:您可以通过侵蚀连续层并记住“边缘”(即在上一次迭代中被擦除的像素)来获得有效的解决方案。因此,不是每次都处理整个图像,而是处理一个小得多的子集,使算法运行的时间与图像区域准成比例。
当执行腐蚀通道时,您保留像素以便擦除它们会修改局部连通性。
【讨论】:
您能否详细说明存储“边缘”的信息有什么帮助?被腐蚀的部分不存在了,下一次腐蚀必须在整个对象上再次处理,对吧? @Meghana:在任何过程中,只需要处理具有异质邻域的白色像素。因此,您保留这些列表并在每次删除时更新列表。以上是关于在 C++ 中计算图像骨架的最快方法的主要内容,如果未能解决你的问题,请参考以下文章