Python:基于深色图像上特定颜色的矩形轮廓(OpenCV)
由于我正在尝试用Python中的OpenCV来提高我的技能,我想知道从一个大部分为深色的图像中提取特定灰度的最佳方法是什么 首先,我创建了一个测试图像,以便使用OpenCV测试不同的方法: 假设我想提取图像中的特定颜色,并为其添加边框。现在我选择了中间的灰色矩形,颜色为(33, 33, 34 RGB),请参阅以下内容: (以下是不带红色边框的图像,以便测试您的想法:) 这是我迄今为止尝试过的,但不太奏效:Python:基于深色图像上特定颜色的矩形轮廓(OpenCV),python,opencv,python-imaging-library,crop,contour,Python,Opencv,Python Imaging Library,Crop,Contour,由于我正在尝试用Python中的OpenCV来提高我的技能,我想知道从一个大部分为深色的图像中提取特定灰度的最佳方法是什么 首先,我创建了一个测试图像,以便使用OpenCV测试不同的方法: 假设我想提取图像中的特定颜色,并为其添加边框。现在我选择了中间的灰色矩形,颜色为(33, 33, 34 RGB),请参阅以下内容: (以下是不带红色边框的图像,以便测试您的想法:) 这是我迄今为止尝试过的,但不太奏效: img = cv2.imread(path) #Read input image hsv
img = cv2.imread(path) #Read input image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # Convert from BGR to HSV color space
saturation_plane = hsv[:, :, 1] # all black/white/gray pixels are zero, and colored pixels are above zero
_, thresh = cv2.threshold(saturation_plane, 8, 255, cv2.THRESH_BINARY) # Apply threshold on s
contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # draw all contours
contours = contours[0] if len(contours) == 2 else contours[1]
result = img.copy()
for contour in contours:
(x, y, w, h) = cv2.boundingRect(contour) # compute the bounding box for the contour
if width is equal to the width of the rectangle i want to extract:
draw contour
如果矩形的大小不是固定的,因此我无法通过其宽度/高度检测到它,该怎么办?此外,将图像转换为灰度而不是HSV是否更好?我只是一个新手,我想听听你如何做到这一点
提前感谢。如果知道具体颜色,您可以从
灰色=np.all(img==(34,33,33),2)开始。
结果是一个逻辑矩阵,其中True
,其中BGR
=(34、33、33)
,如果不是,则为False。注:OpenCV颜色顺序为BGR而非RGB
- 将逻辑矩阵转换为
:uint8
gray=gray.astype(np.uint8)*255
- 在
图像上使用gray
李>findContours
结果: 灰色:
img:
如果您不知道大部分深色的具体颜色,您可能会找到所有轮廓,并搜索灰度值最低的轮廓:
import numpy as np
import cv2
# Read input image
img = cv2.imread('rectangles.png')
# Convert from BGR to Gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply threshold on gray
_, thresh = cv2.threshold(gray, 8, 255, cv2.THRESH_BINARY)
# Find contours on thresh
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # Use index [-2] to be compatible to OpenCV 3 and 4
min_level = 255
min_c = []
#Iterate contours, and find the darkest:
for c in cnts:
x, y, w, h = cv2.boundingRect(c)
# Ignore contours that are very thin (like edges)
if w > 5 and h > 5:
level = gray[y+h//2, x+w//2] # Get gray level of center pixel
if level < min_level:
# Update min_level abd min_c
min_level = level
min_c = c
x, y, w, h = cv2.boundingRect(min_c)
# Draw red rectangle for testing
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), thickness = 2)
# Show result
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
将numpy导入为np
进口cv2
#读取输入图像
img=cv2.imread('rectangles.png')
#从BGR转换为灰色
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
#对灰色应用阈值
_,thresh=cv2.阈值(灰色,8255,cv2.thresh_二进制)
#在thresh上查找轮廓
cnts=cv2。查找到的对象(thresh、cv2.RETR_EXTERNAL、cv2.CHAIN_About_NONE)[-2]#使用索引[-2]与OpenCV 3和OpenCV 4兼容
最低等级=255
min_c=[]
#迭代等高线,并找到最暗的:
对于碳纳米管中的碳:
x、 y,w,h=cv2.boundingRect(c)
#忽略非常薄的轮廓(如边)
如果w>5且h>5:
级别=灰度[y+h//2,x+w//2]#获取中心像素的灰度
如果液位<最小液位:
#更新min_级别abd min_c
最低水平=最低水平
最小值c=c
x、 y,w,h=cv2.boundingRect(最小值)
#绘制红色矩形以进行测试
cv2.矩形(img,(x,y),(x+w,y+h),(0,0,255),厚度=2)
#显示结果
cv2.imshow(“img”,img)
cv2.等待键(0)
cv2.destroyAllWindows()
结果:非常感谢!我知道RGB的值。它至少总是在30-35之间,这意味着它可能是RGB(31,32,33)、RGB(35,35,35)、RGB(30,35,33)等等。如果您知道颜色,请使用cv2.inRange()在颜色的一些上下限内对该颜色设置阈值。@Keanu如果您知道范围,请使用
thresh=cv2.inRange(img,(30,30),(35,35))
正如fmw42评论的那样。@Rotem您的回答真的很有帮助。终于把这一切都弄明白了,谢谢
import numpy as np
import cv2
# Read input image
img = cv2.imread('rectangles.png')
# Convert from BGR to Gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply threshold on gray
_, thresh = cv2.threshold(gray, 8, 255, cv2.THRESH_BINARY)
# Find contours on thresh
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # Use index [-2] to be compatible to OpenCV 3 and 4
min_level = 255
min_c = []
#Iterate contours, and find the darkest:
for c in cnts:
x, y, w, h = cv2.boundingRect(c)
# Ignore contours that are very thin (like edges)
if w > 5 and h > 5:
level = gray[y+h//2, x+w//2] # Get gray level of center pixel
if level < min_level:
# Update min_level abd min_c
min_level = level
min_c = c
x, y, w, h = cv2.boundingRect(min_c)
# Draw red rectangle for testing
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), thickness = 2)
# Show result
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()