简体   繁体   中英

Crop a specific color region (Python + OpenCV)

在此处输入图像描述

I'm having trouble cropping out the pink line on the image. Ideally, I want to crop it the entire pink stretch, it's okay if the blue is included.

What I did

import cv2
import numpy as np 
from PIL import Image, ImageFilter

#convertes image to hsv and applies blur
img = cv2.imread("1501.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2RGB)
fin = cv2.GaussianBlur(hsv,(25,25),cv2.BORDER_DEFAULT)

#divided the image in half to see the target
na = np.array(fin)
orig = na.copy()
m = orig.shape[0]
n = orig.shape[1]/2
M = int(m)
N = int(n)
tiles = [orig[x:x+M,y:y+N] for x in range(0,orig.shape[0]) for y in range(0,orig.shape[1],N)]
variable = tiles[0]
Image.fromarray(variable).save('variable.jpg')

#extracts color from the target
hsv_lower = (300,2.2,71)
hsv_upper = (326,41,32.5)
mask = cv2.inRange(variable, hsv_lower, hsv_upper)

What to do next I'm not sure what to do next, and am unsure if I'm even capturing the pink line in the first place. Python3 solutions are preferred.

You can use findContours to segment out a thresholded blob.

Thresholded Image:

在此处输入图像描述

Filter Contours by size:

在此处输入图像描述

Crop out the contour:

在此处输入图像描述

I have no idea why the color in the output image is blue. If anyone else knows why this is happening I'd love to know because it's driving me a little crazy.

Code:

import cv2
import numpy as np

# load image
img = cv2.imread("band.jpg");

# rescale
scale = 0.25;
h, w = img.shape[:2];
h = int(h*scale);
w = int(w*scale);
img = cv2.resize(img, (w,h));

# hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV);
h, s, v = cv2.split(hsv);

# thresh
thresh = cv2.inRange(h, 140, 160);

# contours
_, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);

# filter contours by size
big_cntrs = [];
marked = img.copy();
for contour in contours:
    area = cv2.contourArea(contour);
    if area > 10000:
        print(area);
        big_cntrs.append(contour);
cv2.drawContours(marked, big_cntrs, -1, (0, 255, 0), 3);

# create a mask of the contoured image
mask = np.zeros_like(h);
mask = cv2.drawContours(mask, big_cntrs, -1, 255, -1);

# crop out
out = np.zeros_like(img) # Extract out the object and place into output image
out[mask == 255] = img[mask == 255];

# show
cv2.imshow("Original", img);
cv2.imshow("thresh", thresh);
cv2.imshow("Marked", marked);
cv2.imshow("out", out);
cv2.waitKey(0);

# save
cv2.imwrite("thresh.png", thresh);
cv2.imwrite("marked.png", marked);
cv2.imwrite("out.png", out);

Edit:

Fixed the blue color issue (changed to "mask = np.zeros_like(h);").

I'm using OpenCV 3.4.2

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