简体   繁体   中英

Find the intersection line between two colors

I'm trying to find the intersection between color green and blue of a set of images that are similar to this one:

在此处输入图像描述

So what I need is something is something like this:

在此处输入图像描述

And because I need to use the contours for some calculus after that I would like to know if it's possible to have the points of the curve in an array or something... but I have no idea if this is possible. I tried to do the mask but I don't think it's going to work... here's the code:

        lower_val = np.array([0, 0, 0])

        upper_val = np.array([150, 255, 150])

        mask = cv2.inRange(image, lower_val, upper_val)
        only_lumen = cv2.bitwise_and(image, image, mask=mask)
        gray = cv2.cvtColor(only_lumen, cv2.COLOR_BGR2GRAY)
        blur = cv2.GaussianBlur(gray, (3, 3), 0)
        thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
        thresh = 255 - thresh

This is how I'm trying to display the points:

    x, y = [i[0] for i in pts_list], [i[1] for i in pts_list]
    max_x, max_y = max(x), max(y)

    image = np.zeros((max_y + 1, max_x + 1))

    for i in range(len(pts_list)):
        image[max_y - y[i], x[i]] = 1

And this is the image I obtain: 在此处输入图像描述

I don't understand why the dots meet in a corner and why the background is violet... The lines where supposed to be in the middel

For now, I will give you the simplest of solutions you can try (can be improved a lot):

Boundary pixels (after getting the masks) will be adjacent to each other but you have to pick a side if you want 1 pixel width boundary as minimum. Alternative to this is to set search kernel and use morphology to dilate your color masks according to your search kernel. The common points in the dilated masks will be the neighborhood points which you can extract by simply doing a Bitwise AND.

# Define the color ranges for each color of interest for creating masks.
COLOR1_RANGE = [(30, 0, 0), (255, 50, 50)]  # Blue in BGR, [(low), (high)].
COLOR2_RANGE = [(0, 30, 0), (50, 255, 50)]  # Green in BGR, [(low), (high)].

# Create masks:
color1_mask = cv2.inRange(self.img, COLOR1_RANGE[0], COLOR1_RANGE[1])
color2_mask = cv2.inRange(self.img, COLOR2_RANGE[0], COLOR2_RANGE[1])

# Adjust according to your adjacency requirement.
kernel = np.ones((3, 3), dtype=np.uint8)

# Dilating masks to expand boundary.
color1_mask = cv2.dilate(color1_mask, kernel, iterations=1)
color2_mask = cv2.dilate(color2_mask, kernel, iterations=1)

# Required points now will have both color's mask val as 255.
common = cv2.bitwise_and(color1_mask, color2_mask)

# Common is binary np.uint8 image, min = 0, max = 255.
# SOME_THRESHOLD can be anything within the above range. (not needed though)
# Extract/Use it in whatever way you want it.
intersection_points = np.where(common > SOME_THRESHOLD)

# Say you want these points in a list form, then you can do this.
pts_list = [[r, c] for r, c in zip(*intersection_points)]
print(pts_list)

Some Sample Outputs:

Input 01 (Simple):
简单输入

Output 01 (Simple):
简单输出

Output Points as List (Partial):

pts_list = [[99, 104], [99, 105], [100, 104], [100, 105], [100, 106], ...]

Input 02 (Complex):
复杂输入

Output 02 (Complex):
复杂输出

Output Points as List (Partial):

pts_list = [[127, 309], [127, 310], [127, 311], [127, 312], [127, 313], ...]

Update 1:
I made a small change in the code comments to make it more understandable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM