Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Just a quick answer. Sorry for the rough code snippets. They are untested and incomplete but might give a rough idea. So the general approach would be to find a filtering function that targets whatever distinguishes the grid lines from the graph line. Three approaches:

1. Filter by Orientation: the grid is strictly horizontal and vertical, the graph not. You can filter by orientation of the gradient (filter out orientation = 0° and 90° etc.). Rough idea (google gradient orientation for more results)

  • Step 1: roughly threshold out weak edges (e.g. cv::threshold(img, img,... 50, BINARY_THRESHOLD))
  • Step 2: take cv::angle(sx, sy) with sx and sy being the vertical and horizontal Sobel (use ksize=5 for more robust results).
  • Step 3: threshold out angles close to 0 and 90 etc. cv::inRange(Scalar(0)...).
  • Step 4: get the points with cv::findNonZero()

2. Filter by Thickness: as sturkmen suggested, morphological filtering is an easy way to filter out thinner lines. It can also be used to filter by line orientation, but will not perform as well as filtering through the gradient. If the thickness differs more than two pixels it should be enough to

  • Step 1: strel =cv::getStructuringElement(MORPH_ELLIPSE, 3, 3)
  • Step2: cv::dilate(img, strel,...)
  • Step 3: cv::threshold( img,...,128, BINARY_INVERSE)
  • Step 4: cv::findNonZero()

3. Filter by Periodicity: the grid is periodic, the graph line not. The grid could be sorted out via the peaks in the Fourier Transform. Problem: not easy to handle if you don't have experience with that, and the grid is not even really periodic in your example. So not an option here.

Just a quick answer. Sorry for the rough code snippets. They are untested and incomplete but might give a rough idea. So the general approach would be to find a filtering function that targets whatever distinguishes the grid lines from the graph line. Three approaches:

1. Filter by Orientation: the grid is strictly horizontal and vertical, the graph not. You can filter by orientation of the gradient (filter out orientation = 0° and 90° etc.). Rough idea (google gradient orientation for more results)

  • Step 1: roughly threshold out weak edges (e.g. cv::threshold(img, img,... 50, BINARY_THRESHOLD))
  • Step 2: take cv::angle(sx, sy) with sx and sy being the vertical and horizontal Sobel (use ksize=5 for more robust results).results), please check if this is the correct code, I'm not sure. You have to calculate the atan2(sx,sy) for each element.
  • Step 3: threshold out angles close to 0 and 90 etc. cv::inRange(Scalar(0)...).
  • Step 4: get the points with cv::findNonZero()

2. Filter by Thickness: as sturkmen suggested, morphological filtering is an easy way to filter out thinner lines. It can also be used to filter by line orientation, but this will not perform probably not work as well as filtering through the gradient. gradient orientation.

If the thickness differs more than two pixels it should be enough to

  • do the following: - Step 1: strel =cv::getStructuringElement(MORPH_ELLIPSE, 3, 3)
  • 3) - Step2: cv::dilate(img, strel,...)
  • strel,...) //repeat this step until the grid has disappeared. - Step 3: cv::threshold( img,...,128, BINARY_INVERSE)
  • BINARY_INVERSE) - Step 4: cv::findNonZero()

3. Filter by Periodicity: the grid is periodic, the graph line not. The grid could be sorted out via the peaks in the Fourier Transform. Problem: not easy to handle if you don't have experience with that, and the grid is not even really periodic in your example. So not an option here.

Just a quick answer. Sorry for the rough code snippets. They are untested and incomplete but might give a rough idea. So the general approach would be to find a filtering function that targets whatever distinguishes the grid lines from the graph line. Three approaches:

1. Filter by Orientation: the grid is strictly horizontal and vertical, the graph not. You can filter by orientation of the gradient (filter out orientation = 0° and 90° etc.). Rough idea (google gradient orientation for more results)

  • Step 1: roughly threshold out weak edges (e.g. cv::threshold(img, img,... 50, BINARY_THRESHOLD))
  • Step 2: take cv::angle(sx, sy) with sx and sy being the vertical and horizontal Sobel (use ksize=5 for more robust results), please check if this is the correct code, I'm not sure. You have to calculate the atan2(sx,sy) for each element.
  • Step 3: threshold out angles close to 0 and 90 etc. cv::inRange(Scalar(0)...).
  • Step 4: get the points with cv::findNonZero()

2. Filter by Thickness: as user sturkmen suggested, suggested in the comment above, morphological filtering is an easy way to filter out thinner lines. It can also be used to filter by line orientation, but this will probably not work as well as filtering through the gradient orientation.

If the thickness differs more than two pixels it should be enough to do the following: - Step 1: strel =cv::getStructuringElement(MORPH_ELLIPSE, 3, 3) - Step2: cv::dilate(img, strel,...) //repeat this step until the grid has disappeared. - Step 3: cv::threshold( img,...,128, BINARY_INVERSE) - Step 4: cv::findNonZero()

3. Filter by Periodicity: the grid is periodic, the graph line not. The grid could be sorted out via the peaks in the Fourier Transform. Problem: not easy to handle if you don't have experience with that, and the grid is not even really periodic in your example. So not an option here.

Just a quick answer. Sorry for the rough code snippets. They are untested and incomplete but might give a rough idea. So the general approach would be to find a filtering function that targets whatever distinguishes the grid lines from the graph line. Three approaches:

1. Filter by Orientation: the grid is strictly horizontal and vertical, the graph not. You can filter by orientation of the gradient (filter out orientation = 0° and 90° etc.). Rough idea (google gradient orientation for more results)

  • Step 1: roughly threshold out weak edges (e.g. cv::threshold(img, img,... 50, BINARY_THRESHOLD))
  • Step 2: take cv::angle(sx, sy) with sx and sy being the vertical and horizontal Sobel (use ksize=5 for more robust results), please check if this is the correct code, I'm not sure. You have to calculate the atan2(sx,sy) for each element.
  • Step 3: threshold out angles close to 0 and 90 etc. cv::inRange(Scalar(0)...).
  • Step 4: get the points with cv::findNonZero()

2. Filter by Thickness: as user sturkmen suggested in the comment above, morphological filtering is an easy way to filter out thinner lines. It can also be used to filter by line orientation, but this will probably not work as well as filtering through the gradient orientation.

If the thickness of the lines of the grid and the plot differs more than two pixels pixels, it should be enough to do the following: - Step 1: strel =cv::getStructuringElement(MORPH_ELLIPSE, 3, 3) - Step2: cv::dilate(img, strel,...) //repeat this step until the grid has disappeared. disappeared (can be done by setting the iterations or by manually calling the function several times). - Step 3: cv::threshold( img,...,128, BINARY_INVERSE) - Step 4: cv::findNonZero()

3. Filter by Periodicity: the grid is periodic, the graph line not. The grid could be sorted out via the peaks in the Fourier Transform. Problem: not easy to handle if you don't have experience with that, and the grid is not even really periodic in your example. So not an option here.