使用Python查找图像中的红色&;OpenCV
我试图从图像中提取红色。我有一个应用阈值的代码,只保留指定范围内的值:使用Python查找图像中的红色&;OpenCV,python,image,opencv,image-processing,hsv,Python,Image,Opencv,Image Processing,Hsv,我试图从图像中提取红色。我有一个应用阈值的代码,只保留指定范围内的值: img=cv2.imread('img.bmp') img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV) lower_red = np.array([0,50,50]) #example value upper_red = np.array([10,255,255]) #example value mask = cv2.inRange(img_hsv, lower_red, upper_r
img=cv2.imread('img.bmp')
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_red = np.array([0,50,50]) #example value
upper_red = np.array([10,255,255]) #example value
mask = cv2.inRange(img_hsv, lower_red, upper_red)
img_result = cv2.bitwise_and(img, img, mask=mask)
但是,正如我所检查的,红色的色调值可以在0到10之间,也可以在170到180之间。因此,我想保留这两个范围中任何一个的值。我尝试将阈值从10设置为170,并使用cv2.bitwise_not()
函数,但随后我也得到了所有白色。我认为最好的选择是为每个范围创建一个遮罩并同时使用它们,所以我必须在继续之前将它们连接在一起
有没有一种方法可以使用OpenCV连接两个面具?还是有其他方法可以实现我的目标
编辑。我带来的不是很优雅,但很有效的解决方案:
image_result = np.zeros((image_height,image_width,3),np.uint8)
for i in range(image_height): #those are set elsewhere
for j in range(image_width): #those are set elsewhere
if img_hsv[i][j][1]>=50 \
and img_hsv[i][j][2]>=50 \
and (img_hsv[i][j][0] <= 10 or img_hsv[i][j][0]>=170):
image_result[i][j]=img_hsv[i][j]
image\u result=np.zero((图像高度,图像宽度,3),np.uint8)
对于范围内的i(图像高度):#这些设置在别处
对于范围内的j(图像宽度):#这些在别处设置
如果img_hsv[i][j][1]>=50\
和img_hsv[i][j][2]>=50\
及(img_hsv[i][j][0]=170):
图像结果[i][j]=img_hsv[i][j]
它基本上满足了我的需求,OpenCV的函数可能也能满足我的需求,但如果有更好的方法(使用一些专用函数并编写更少的代码),请与我分享。:) 我只需将遮罩添加在一起,然后使用
np.where
遮罩原始图像
img=cv2.imread("img.bmp")
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# lower mask (0-10)
lower_red = np.array([0,50,50])
upper_red = np.array([10,255,255])
mask0 = cv2.inRange(img_hsv, lower_red, upper_red)
# upper mask (170-180)
lower_red = np.array([170,50,50])
upper_red = np.array([180,255,255])
mask1 = cv2.inRange(img_hsv, lower_red, upper_red)
# join my masks
mask = mask0+mask1
# set my output img to zero everywhere except my mask
output_img = img.copy()
output_img[np.where(mask==0)] = 0
# or your HSV image, which I *believe* is what you want
output_hsv = img_hsv.copy()
output_hsv[np.where(mask==0)] = 0
这应该比在图像的每个像素上循环要快得多,可读性也要高得多。玩这个吧
#blurring and smoothin
img1=cv2.imread('marathon.png',1)
hsv = cv2.cvtColor(img1,cv2.COLOR_BGR2HSV)
#lower red
lower_red = np.array([0,50,50])
upper_red = np.array([10,255,255])
#upper red
lower_red2 = np.array([170,50,50])
upper_red2 = np.array([180,255,255])
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(img1,img1, mask= mask)
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
res2 = cv2.bitwise_and(img1,img1, mask= mask2)
img3 = res+res2
img4 = cv2.add(res,res2)
img5 = cv2.addWeighted(res,0.5,res2,0.5,0)
kernel = np.ones((15,15),np.float32)/225
smoothed = cv2.filter2D(res,-1,kernel)
smoothed2 = cv2.filter2D(img3,-1,kernel)
cv2.imshow('Original',img1)
cv2.imshow('Averaging',smoothed)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
cv2.imshow('mask2',mask2)
cv2.imshow('res2',res2)
cv2.imshow('res3',img3)
cv2.imshow('res4',img4)
cv2.imshow('res5',img5)
cv2.imshow('smooth2',smoothed2)
cv2.waitKey(0)
cv2.destroyAllWindows()
要检测红色,可以使用HSV颜色阈值脚本确定下限/上限阈值,然后
cv2.bitwise_和()
获得遮罩。使用此输入图像
我们得到了这个结果并屏蔽了它
代码
带滑块的HSV颜色阈值脚本,请记住更改图像文件路径
import cv2
import sys
import numpy as np
def nothing(x):
pass
# Load in image
image = cv2.imread('1.jpg')
# Create a window
cv2.namedWindow('image')
# create trackbars for color change
cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv
cv2.createTrackbar('SMin','image',0,255,nothing)
cv2.createTrackbar('VMin','image',0,255,nothing)
cv2.createTrackbar('HMax','image',0,179,nothing)
cv2.createTrackbar('SMax','image',0,255,nothing)
cv2.createTrackbar('VMax','image',0,255,nothing)
# Set default value for MAX HSV trackbars.
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)
# Initialize to check if HSV min/max value changes
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0
output = image
wait_time = 33
while(1):
# get current positions of all trackbars
hMin = cv2.getTrackbarPos('HMin','image')
sMin = cv2.getTrackbarPos('SMin','image')
vMin = cv2.getTrackbarPos('VMin','image')
hMax = cv2.getTrackbarPos('HMax','image')
sMax = cv2.getTrackbarPos('SMax','image')
vMax = cv2.getTrackbarPos('VMax','image')
# Set minimum and max HSV values to display
lower = np.array([hMin, sMin, vMin])
upper = np.array([hMax, sMax, vMax])
# Create HSV Image and threshold into a range.
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower, upper)
output = cv2.bitwise_and(image,image, mask= mask)
# Print if there is a change in HSV value
if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
phMin = hMin
psMin = sMin
pvMin = vMin
phMax = hMax
psMax = sMax
pvMax = vMax
# Display output image
cv2.imshow('image',output)
# Wait longer to prevent freeze for videos.
if cv2.waitKey(wait_time) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
以防有人感兴趣。我正在使用嵌入式设备,比如Raspberry Pi。对于这样的设备,下一个操作id非常重:output_img[np.where(mask==0)]=0。它可以替换为更快的一个:output\u img=cv2。按位和(output\u img,output\u img,mask=mask)您是如何找到范围的?
import cv2
import sys
import numpy as np
def nothing(x):
pass
# Load in image
image = cv2.imread('1.jpg')
# Create a window
cv2.namedWindow('image')
# create trackbars for color change
cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv
cv2.createTrackbar('SMin','image',0,255,nothing)
cv2.createTrackbar('VMin','image',0,255,nothing)
cv2.createTrackbar('HMax','image',0,179,nothing)
cv2.createTrackbar('SMax','image',0,255,nothing)
cv2.createTrackbar('VMax','image',0,255,nothing)
# Set default value for MAX HSV trackbars.
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)
# Initialize to check if HSV min/max value changes
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0
output = image
wait_time = 33
while(1):
# get current positions of all trackbars
hMin = cv2.getTrackbarPos('HMin','image')
sMin = cv2.getTrackbarPos('SMin','image')
vMin = cv2.getTrackbarPos('VMin','image')
hMax = cv2.getTrackbarPos('HMax','image')
sMax = cv2.getTrackbarPos('SMax','image')
vMax = cv2.getTrackbarPos('VMax','image')
# Set minimum and max HSV values to display
lower = np.array([hMin, sMin, vMin])
upper = np.array([hMax, sMax, vMax])
# Create HSV Image and threshold into a range.
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower, upper)
output = cv2.bitwise_and(image,image, mask= mask)
# Print if there is a change in HSV value
if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
phMin = hMin
psMin = sMin
pvMin = vMin
phMax = hMax
psMax = sMax
pvMax = vMax
# Display output image
cv2.imshow('image',output)
# Wait longer to prevent freeze for videos.
if cv2.waitKey(wait_time) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()