Elegir los límites HSV superior e inferior correctos para la detección de color con `cv::inRange` (OpenCV)

Resuelto Student FourK asked hace 12 años • 10 respuestas

Tengo una imagen de una lata de café con tapa naranja en la posición de la cual quiero encontrar. Aquí es imagen.

La utilidad gcolor2 muestra que HSV en el centro de la tapa es (22, 59, 100). La pregunta es ¿cómo elegir entonces los límites del color? Probé min = (18, 40, 90) y max = (27, 255, 255), pero obtuve resultados inesperados.resultado

Aquí está el código Python:

import cv

in_image = 'kaffee.png'
out_image = 'kaffee_out.png'
out_image_thr = 'kaffee_thr.png'

ORANGE_MIN = cv.Scalar(18, 40, 90)
ORANGE_MAX = cv.Scalar(27, 255, 255)
COLOR_MIN = ORANGE_MIN
COLOR_MAX = ORANGE_MAX

def test1():
    frame = cv.LoadImage(in_image)
    frameHSV = cv.CreateImage(cv.GetSize(frame), 8, 3)
    cv.CvtColor(frame, frameHSV, cv.CV_RGB2HSV)
    frame_threshed = cv.CreateImage(cv.GetSize(frameHSV), 8, 1)
    cv.InRangeS(frameHSV, COLOR_MIN, COLOR_MAX, frame_threshed)
    cv.SaveImage(out_image_thr, frame_threshed)

if __name__ == '__main__':
    test1()
Student FourK avatar Jun 08 '12 19:06 Student FourK
Aceptado

Problema 1: diferentes aplicaciones utilizan diferentes escalas para HSV. Por ejemplo, utiliza gimp H = 0-360, S = 0-100 and V = 0-100. Pero OpenCV usa H: 0-179, S: 0-255, V: 0-255. Aquí obtuve un valor de tono de 22 en gimp. Así que tomé la mitad, 11, y definí el rango para eso. es decir (5,50,50) - (15,255,255).

Problema 2: Y además, OpenCV usa el formato BGR, no RGB. Entonces cambie su código que convierte RGB a HSV de la siguiente manera:

cv.CvtColor(frame, frameHSV, cv.CV_BGR2HSV)

Ahora ejecútelo. Obtuve un resultado de la siguiente manera:

ingrese la descripción de la imagen aquí

Espero que eso sea lo que querías. Hay algunas detecciones falsas, pero son pequeñas, por lo que puedes elegir el contorno más grande que es tu párpado.

EDITAR:

Como dijo Karl Philip en su comentario, sería bueno agregar un código nuevo. Pero hay cambio de una sola línea. Por lo tanto, me gustaría agregar el mismo código implementado en el nuevo cv2módulo, para que los usuarios puedan comparar la facilidad y flexibilidad del nuevo cv2módulo.

import cv2
import numpy as np

img = cv2.imread('sof.jpg')

ORANGE_MIN = np.array([5, 50, 50],np.uint8)
ORANGE_MAX = np.array([15, 255, 255],np.uint8)

hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

frame_threshed = cv2.inRange(hsv_img, ORANGE_MIN, ORANGE_MAX)
cv2.imwrite('output2.jpg', frame_threshed)

Da el mismo resultado que el anterior. Pero el código es mucho más simple.

Abid Rahman K avatar Jun 08 '2012 14:06 Abid Rahman K

Ok, encontrar color en HSVel espacio es una pregunta antigua pero común. Hice una hsv-colormapbúsqueda rápida de un color especial. Aquí lo tienes:

ingrese la descripción de la imagen aquí

El eje x representa Hueen [0,180), el eje y1 representa Saturationen [0,255], el eje y2 representa S = 255, mientras se mantiene V = 255.

Para encontrar un color, generalmente simplemente busque el rango de Hy Sy establezca v en el rango (20, 255).

Para encontrar el color naranja, buscamos en el mapa y encontramos el mejor rango: H :[10, 25], S: [100, 255], and V: [20, 255]. Entonces la máscara escv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )

Luego usamos el rango encontrado para buscar el color naranja, este es el resultado:

ingrese la descripción de la imagen aquí


El método es simple pero común de usar:

#!/usr/bin/python3
# 2018.01.21 20:46:41 CST
import cv2

img = cv2.imread("test.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )
cv2.imshow("orange", mask);cv2.waitKey();cv2.destroyAllWindows()

Respuestas similares:

  1. Cómo definir un valor umbral para detectar solo objetos de color verde en una imagen: Opencv

  2. Elegir valores HSV correctos para el umbral de OpenCV con InRangeS

Kinght 金 avatar Jan 21 '2018 13:01 Kinght 金

Aquí hay un script de umbral de color HSV simple para determinar los rangos de color inferior/superior usando barras de seguimiento para cualquier imagen en el disco. Simplemente cambie la ruta de la imagen en cv2.imread(). Ejemplo para aislar naranja:

ingrese la descripción de la imagen aquí

import cv2
import numpy as np

def nothing(x):
    pass

# Load image
image = cv2.imread('1.jpg')

# Create a window
cv2.namedWindow('image')

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
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 HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

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 maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = 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 result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

Rangos de umbral de color inferior/superior de HSV

(hMin = 0 , sMin = 164, vMin = 0), (hMax = 179 , sMax = 255, vMax = 255)

Una vez que haya determinado sus gamas de colores lowery upperlas de HSV, puede segmentar los colores deseados de esta manera:

import numpy as np
import cv2

image = cv2.imread('1.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 164, 0])
upper = np.array([179, 255, 255])
mask = cv2.inRange(hsv, lower, upper)
result = cv2.bitwise_and(image, image, mask=mask)

cv2.imshow('result', result)
cv2.waitKey()
nathancy avatar Jan 25 '2020 03:01 nathancy