# Image Recognition Method, calculate deviation from rectangular grid

I have a set-up which creates pictures of a grid that is a bit bend towards the ends, and I need some kind of program that can calculate the deviation, resp. it just needs to be some kind of indicator, a stronger deviation (strong bend) leads to higher number and something close to a perfect rectangular grid will lead to a number close to zero. What possibilities do I have to do that? I'm just asking for the Method. I can't use neural networks since I have little data, I can't generate lots of pictures. Is there any other method to implement a solution to that problem?

Here's an example picture of the grid:

I need a program that calculates the mean deviation of the red lines from the perfect rectangular grid. What methods exists for such kind of problem apart from neural networks?

• why not just computing the distance ($y_{standard} - y_{curved}$) between the standard grid and the curved one? Mar 21 at 19:22
• thank you for your reply, how can I compute the distance? I don't have any units of length or anything like that I only have the picture, which I could convert into pixel data (a matrix of zeros and ones representing white and black resp. red) Mar 21 at 20:27

So, here's an idea, not perfect but it should give you at least a starting point.

• Start by converting your image into a binary grayscale one, to detect the lines of both curved and straight grid.
• Detect keypoints on left and right sides of the grayscale mask (see plot below)
• use the keypoints to compute distances.

The last step is the most tricky. Theoretically it should be possible to detect if 2 points belong to the straight grid by comparing their values (cause the y coordinate should be the same). In practice it's not always the case. This detection is important to understand which pairs of values to subtract (point that belong to straight grid - next point in the list, curved one). Also, if all points belong to the straight grid, you know you have 2 straight grids.

I think its possible to refine the methods by getting pairs of left/right points and computing the slope of the line they form, if the slope value is lower than a threshold (close enough to 0) then again we can safely assume the 2 point belongs to the straight grid.

I didn't implement yet this step, but if you find it hard I could try, just don't want to spend too much time on it to then find that is not useful for you

Note also that the same procedure could be then applied not only on the edges bu to all vertical lines of the image.

code so far:

from skimage.io import imread
import matplotlib.pyplot as plt
import numpy as np

def main(filename):

# convert to binary grayscale for convinience
gray = img.mean(axis=2)
gray = gray < 255

# get indicies of keypoints on both side of the image
y_right = np.argwhere(gray[:, -1] != 0)[:, 0]
y_left = np.argwhere(gray[:, 0] != 0)[:, 0]

# get values as well
y_right_values = np.where(gray[:, -1] != 0)[0]
y_left_values = np.where(gray[:, 0] != 0)[0]

# generate x coordinates [0 and width of image]
x_right = np.array([gray.shape[1] for _ in range(len(y_right))])
x_left = np.array([0 for _ in range(len(y_left))])

# get points with same y coordinate (belonging to straight lines)
distances_right = compute_distance(y_right_values, y_left_values)
distances_left = compute_distance(y_left_values, y_right_values)
print(
f"Average distance cruved vs straght: {(np.mean(distances_right)+np.mean(distances_left)) / 2}"
)

# plot
plt.imshow(gray)
plt.scatter(x_right, y_right, color="r")
plt.scatter(x_left, y_left, color="r")
plt.show()

def compute_distance(points, points_reference):
"""Compute distances between keypoints

Parameters
----------
points :
points for which the distances should be conputed
points_reference : TYPE
points on the other side of the image, used to check if a point belong to the
straight grid
distances : TYPE
list filled with computed distances

Returns
-------
TYPE

"""
distances = []
points = [p for p in points]
ref = [p for p in points_reference]
while points:
# if point share value with a point to the left, it's part of the straight grid
if points[0] in ref:
distances.append(np.abs(points[1] - points[0]))
# remove points from list
points.pop(0)
points.pop(0)
# if first point doesn't belong to the straight grid, skip
else:
points.pop(0)
return distances

if __name__ == "__main__":

filename = "HCi6P.png"
main(filename)

[1]: https://i.stack.imgur.com/ePPQQ.png