我需要从一张纸的照片中得到线条。在重新思考时,我遇到了这个,其中一个答案提到了这个博客条目。
现在我在使用这种方法时遇到了麻烦。我已按如下方式实现它(使用 OpenCV 的 c++ 接口:
// the image has to be grayscale
if (image.channels() != 1)
{
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
}
// we need to enhance the lighting before we can threshold the photography
cv::equalizeHist(image, image);
// a binary image is needed
cv::threshold(image, image, threshold, 255, cv::THRESH_BINARY);
cv::imwrite("thresholdedImage.jpg", image);
// the resulting skeleton
cv::Mat skeleton(image.size(), CV_8UC1, cv::Scalar(0,0,0));
// needed if in-place processing is not possible
cv::Mat temp(image.size(), CV_8UC1);
// eroded image is saved here
cv::Mat eroded;
// needed for morphological transforms (erodation, dilation)
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3,3));
bool done = true;
int i = 0;
while(done)
{
// eroding + dilating = opening
cv::erode(image, eroded, element);
cv::dilate(eroded, temp, element);
cv::subtract(image, temp, temp);
cv::bitwise_or(skeleton, temp, skeleton);
eroded.copyTo(image);
done = (cv::countNonZero(image) == 0);
++i;
}
为了概念验证,我决定使用计算机制作的绘图进行测试,以消除早期阶段的照明问题。这可以在这里看到:
阈值是正确的,但不幸的是骨架看起来很奇怪:
我已经绘制了 100 次迭代后的骨架,它看起来像这样:
你有什么建议吗?