【问题标题】:Crop a specific color region (Python + OpenCV)裁剪特定颜色区域(Python + OpenCV)
【发布时间】:2021-05-05 09:19:45
【问题描述】:

我无法裁剪图像上的粉红色线条。理想情况下,我想裁剪整个粉色部分,如果包括蓝色就可以了。

我做了什么

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)

下一步该做什么 我不确定下一步该做什么,也不确定我是否一开始就捕捉到了粉红线。首选 Python3 解决方案。

【问题讨论】:

  • hsv = cv2.cvtColor(img, cv2.COLOR_RGB2RGB)?你不是说cv2.COLOR_BGR2HSV吗?另外,请注意color conversions 上的文档:H 的值设置为[0 ... 180] 的范围以用于常见的 8 位图像。您可能想看看 this earlier answer from me 作为使用 HSV/HLS 颜色空间的颜色阈值的起点。

标签: python opencv image-processing python-imaging-library crop


【解决方案1】:

您可以使用 findContours 分割出阈值的 blob。

阈值图像:

按大小过滤轮廓:

裁剪轮廓:

我不知道为什么输出图像中的颜色是蓝色的。如果其他人知道为什么会发生这种情况,我很想知道,因为这让我有点发疯。

代码:

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);

编辑:

修复了蓝色问题(更改为“mask = np.zeros_like(h);”)。

我正在使用 OpenCV 3.4.2

【讨论】:

  • 问题出在:mask = np.zeros_like(img)mask = cv2.drawContours(mask, big_cntrs, -1, 255, -1)。您初始化一个三通道图像,但只写入第一个通道,这样第二个和第三个通道中的掩码都是空的。因此,out[mask == 255] = img[mask == 255] 只复制第一个通道,它是蓝色的,因为 OpenCV 使用 BGR 颜色排序。在另一个问题上:Python 不需要尾随 ;。此外,您似乎使用 OpenCV 3.x.x(参见您的 findContours 电话)。您应该说明这一点,因为人们在使用最新的 4.x.x 版本时不会让您的代码运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 2014-03-17
相关资源
最近更新 更多