Alexander
Alexander

Reputation: 13

How to determine if two pixels belong to the same line

I have two white lines on a black background. I need to input the coordinates of two white pixels and get an answer whether these pixels belong to the same line. Lines are one pixel wide.

image

Upvotes: 1

Views: 489

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207405

Here's what I was suggesting in the comments.... starting at either white pixel, floodfill with black. Check colour of other starting pixel. If it's still white, it can't be on the same line we just filled with black.

import cv2

# Load image as greyscale
im = cv2.imread('lines.png', cv2.IMREAD_GRAYSCALE)

w1x, w1y = 171, 108     # bottom line, right end
w2x, w2y = 86, 124      # bottom line. left end
w3x, w3y = 44, 74       # top line, left end
w4x, w4y = 143,25       # top line, right end

# Floodfill with black starting at white px 1
cv2.floodFill(im, None, (w1x,w1y), newVal=0, loDiff=50, upDiff=50, flags=8)
    
# Check white px 2
print(im[w2y, w2x])      # prints 0 because white px 2 is on same line as white px 1

# Check white px 3
print(im[w3y, w3x])      # prints 255, because white px 3 is on other line 

# Check white px 4
print(im[w4y, w4x])      # prints 255, because white px 4 is on other line 

enter image description here


Here's the other approach I was suggesting in the comments... join the two points with a white line and see how many objects are now in the image. If there are still 2, we drew along one of the lines. If there is now 1 object, the line we constructed must have joined the other two objects together into a single, larger object:

import cv2
im = cv2.imread('lines.png', cv2.IMREAD_GRAYSCALE)

# Count objects - initially 2
nObjects = len(cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0])

# Draw white line connecting white px 1 and white px 2
cv2.line(im,(w1x,w1y),(w2x,w2y),255,1)

# Count objects - still 2
nObjects = len(cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0])

# Draw white line connecting white px 1 and white px 3
cv2.line(im,(w1x,w1y),(w3x,w3y),255,1)

# Count objects - now just 1
nObjects = len(cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0])

enter image description here

Upvotes: 0

Gabriel A.
Gabriel A.

Reputation: 641

Given the constraints of this problem, you can just traverse the path between the two white pixels, summing how many white pixels there are between that path. If they are on the same line, you will sum a lot, otherwise, most of the path will be on the black. Also, you should normalize the sum by the path length, and compare the result to a given threshold.

//x1, y1, x2, y2 and img given as input
double len = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) + 0.0001;
double dx = (x2-x1)/len; // Division by zero safe
double dy = (y2-y1)/len;
int sum = 0;
for (int i=0; i<len; ++i) {
    int x = x1 + (dx*i + 0.5); // 0.5 for rounding when truncating
    int y = y1 + (dy*i + 0.5);
    sum += img.at<uchar>(y,x) > 200; // White value higher than 200
}
if (sum > len * 0.5) { // 0.5 is the threshold
    return 1; // They are on the same line
}
return 0; // Else they are on different lines

Beware of the rounding parameter that I choose as 0.5, it depends on how you are generating that lines.

Upvotes: 3

Related Questions