问题
I'm using OpenCV via Python 3.7. I have a following image (please take note of some red pixels on white areas):
I know x and y coordinates of every red pixel in the image. I want to find all red pixels pairs that're interconnected by single white lines.
Let's label every red pixel with id (blue number):
As you can see, the topmost red pixel labeled "1" has only two straight connections: one with a red pixel labeled "2" and one with a red pixel labeled "3". I'd like to get a list of tuples, where every tuple is a pair of interconnected pixels ids. For the image above the correct result is:
[(1,2),
(1,3),
(2,4),
(4,5),
(3,5),
(5,7),
(7,9),
(4,6),
(6,8),
(6,7),
(8,10),
(9,11),
(10,11),
(11,13),
(10,12),
(12,13),
(12,14),
(13,14)]
I haven't composed any code yet, because I can only go with a clumsy homemade algorythm that scans N neighbours of every red pixel to detect directions. I'm sure there're more efficient solutions that utilize built-in functions.
Are there any OpenCV functions that can help with this task?
回答1:
This answer explains how to use np.count_nonzero()
to determine if two points are connected by a white line.
First, draw your image and count the non-zero pixels. There are 18896 non-zero pixels in this example image.
import cv2
import numpy as np
import itertools
# Function that converts an image to single channel and counts non-black pixels
def count_non_zero(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return np.count_nonzero(gray)
# Create source image
img = np.zeros((456,456, 3), np.uint8)
redCoordinates = [(123,123),(345,123),(345,345)]
cv2.line(img, redCoordinates[0], redCoordinates[1], (255,255,255), 65)
for coordinate in redCoordinates: cv2.circle(img, coordinate, 14, (0,0,255), -1)
# Count the non-zero pixels in the image
base = count_non_zero(img)
Next, iterate through each combination of pairs of red coordaintes. Draw a line between the points. Check if the image has the same number of non zero pixels.
# Iterate through each combination of the redCoordinates
idx = 0
for a,b in list(itertools.combinations(redCoordinates, 2)):
# Draw a line between the two points
test_img = cv2.line(img.copy(), a, b, (234,0,234), 5)
# Recount to see if the images are the same
if count_non_zero(test_img) == base: print(a, b, " are connected.")
else: print(a,b, " are NOT connected.")
These are some points that are connected:
These are some points that are not connected:
This is the output of the script:
(123, 123) (345, 123) are connected.
(123, 123) (345, 345) are NOT connected.
(345, 123) (345, 345) are NOT connected.
来源:https://stackoverflow.com/questions/57987251/is-it-possible-to-detect-pairs-of-connected-pixels