# OpenCV: Problem at creating a Skeleton of Lines

I need to get the lines from a photographie of a sheet of paper. While recherching, I came along this, where one answer referred to this blog entry.
Now I am having trouble with this approach. I have implemented it as follows (with the c++-interface of OpenCV:

// 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;
}


For proof of concept, I decide to use a computer-made drawing for testing purposes, to eliminate issues with lighting at this early stage. This can be seen here: The threshold is correct, but unfortunately the skeleton looks very strange: I have drawn the skeleton after 100 iterations, where it looked like this:
Do you have any suggestions?

• That looks like the right skeleton (to the first 100 iterations) of the bright background area. Have you tried inverting the image? – Niki Estner Aug 30 '13 at 7:47
• Now I have tried, and it works! May you post this as an answer? – BlackMamba Aug 30 '13 at 8:56

You are actually drawing the skeleton of the background (brighter region).

change

cv::threshold(image, image, threshold, 255, cv::THRESH_BINARY);


cv::threshold(image, image, threshold, 255, cv::THRESH_BINARY_INV);