De juiste bovenste en onderste HSV-grenzen kiezen voor kleurdetectie met`cv::inRange` (OpenCV)

Ik heb een afbeelding van een koffieblik met een oranje dekselpositie die ik wil vinden.
Hier is het .

Het hulpprogramma gcolor2 toont HSV in het midden van het deksel (22, 59, 100).
De vraag is hoe je dan de grenzen van de kleur kiest? Ik heb min = (18, 40, 90) en max = (27, 255, 255) geprobeerd, maar kreeg onverwachts

Hier is de Python-code:

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

Antwoord 1, autoriteit 100%

Probleem 1:Verschillende toepassingen gebruiken verschillende schalen voor HSV. Gimp gebruikt bijvoorbeeld H = 0-360, S = 0-100 and V = 0-100. Maar OpenCV gebruikt H: 0-179, S: 0-255, V: 0-255. Hier kreeg ik een tintwaarde van 22 in gimp. Dus ik nam de helft ervan, 11, en gedefinieerde bereik daarvoor. dat wil zeggen (5,50,50) - (15,255,255).

Probleem 2:En ook gebruikt OpenCV het BGR-formaat, niet RGB. Dus verander je code die RGB naar HSV converteert als volgt:

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

Voer het nu uit. Ik kreeg de volgende output:

Ik hoop dat je dat wilde. Er zijn enkele valse detecties, maar ze zijn klein, dus je kunt de grootste contour kiezen, dat is je ooglid.

BEWERKEN:

Zoals Karl Philipin zijn commentaar vertelde, zou het goed zijn om nieuwe code toe te voegen. Maar er is verandering van slechts een enkele regel. Ik zou dus dezelfde code willen toevoegen die is geïmplementeerd in de nieuwe cv2-module, zodat gebruikers het gemak en de flexibiliteit van de nieuwe cv2-module kunnen vergelijken.

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)

Het geeft hetzelfde resultaat als hierboven. Maar code is veel eenvoudiger.


Antwoord 2, autoriteit 51%

Ok, vind kleur in HSVruimte is een oude maar veel voorkomende vraag. Ik heb een hsv-colormapgemaakt om snel speciale kleuren op te zoeken. Hier is het:

De x-as staat voor Huein [0,180), de y-as1 staat voor Saturationin [0,255], de y-as2 staat voor S = 255, terwijl u V = 255houdt.

Om een ​​kleur te vinden, zoekt u gewoonlijk het bereik van Hen Sop en stelt u v in bereik (20, 255).

Om de oranje kleur te vinden, zoeken we de kaart op en vinden het beste bereik: H :[10, 25], S: [100, 255], and V: [20, 255]. Het masker is dus cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )

Vervolgens gebruiken we het gevonden bereik om de oranje kleur te zoeken, dit is het resultaat:


De methode is eenvoudig maar algemeen in gebruik:

#!/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()

Vergelijkbare antwoorden:

  1. Hoe een drempelwaarde te definiëren om alleen groene kleurobjecten in een afbeelding te detecteren :Opencv

  2. De juiste HSV-waarden kiezen voor OpenCV-drempels met InRangeS


Antwoord 3, autoriteit 27%

Hier is een eenvoudig HSV-kleurdrempelscript om de onderste/bovenste kleurbereiken te bepalen met behulp van trackbars voor elke afbeelding op de schijf. Verander eenvoudig het afbeeldingspad in cv2.imread()

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

Antwoord 4, autoriteit 19%

Ik heb dit eenvoudige programma gemaakt om HSV-codes in realtime te krijgen

import cv2
import numpy as np
cap = cv2.VideoCapture(0)
def nothing(x):
    pass
# Creating a window for later use
cv2.namedWindow('result')
# Starting with 100's to prevent error while masking
h,s,v = 100,100,100
# Creating track bar
cv2.createTrackbar('h', 'result',0,179,nothing)
cv2.createTrackbar('s', 'result',0,255,nothing)
cv2.createTrackbar('v', 'result',0,255,nothing)
while(1):
    _, frame = cap.read()
    #converting to HSV
    hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
    # get info from track bar and appy to result
    h = cv2.getTrackbarPos('h','result')
    s = cv2.getTrackbarPos('s','result')
    v = cv2.getTrackbarPos('v','result')
    # Normal masking algorithm
    lower_blue = np.array([h,s,v])
    upper_blue = np.array([180,255,255])
    mask = cv2.inRange(hsv,lower_blue, upper_blue)
    result = cv2.bitwise_and(frame,frame,mask = mask)
    cv2.imshow('result',result)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()

Antwoord 5, autoriteit 4%

Het OpenCV HSV-bereik is:
H: 0 tot 179
S: 0 tot 255
V: 0 tot 255

Op Gimp (of andere fotomanipulatie-sw) Hue-bereik van 0 tot 360, aangezien opencv kleurinformatie in een enkele byte plaatst, is de maximale getalswaarde in een enkele byte 255, daarom zijn openCV Hue-waarden gelijk aan Hue-waarden van gimp gedeeld door 2.

Ik ontdekte toen ik objectdetectie probeerde uit te voeren op basis van HSV-kleurruimte dat een bereik van 5 (opencv-bereik) voldoende was om een ​​specifieke kleur eruit te filteren. Ik raad je aan om een ​​HSV-kleurenpalet te gebruiken om erachter te komen welk bereik het beste werkt voor jouw toepassing.


Antwoord 6, autoriteit 4%

Ik heb voor dit doel een eenvoudige (meer geschikte) tool gemaakt met opencv-python. Ik dacht dat het nuttig zou zijn als iemand hier struikelde zoals ik eerder dit jaar deed

Omdat de tool zelf is geschreven met python cv2, zou het gegarandeerd hetzelfde bereik gebruiken. Er is ook een schuifregelaar voor erodeen dilate, aangezien computervisieprojecten deze twee functies meestal nodig hebben

Je kunt de tool vanaf hier klonen https://github.com/hariangr/HsvRangeTool


Antwoord 7, autoriteit 3%

Probeer de volgende commando’s in de Python-terminal om de HSV-waarde van Groen te vinden

green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]

Antwoord 8

U kunt GIMP of PaintDotNet gebruiken om het exacte bereik van HSV te krijgen. Maar het probleem is dat het HSV-bereik in grafische software verschilt van hetzelfde bereik in OpenCV, dus je hebt een functie nodig om dit voor je te corrigeren. Hiervoor kunt u de volgende functie gebruiken.

def fixHSVRange(h, s, v):
    # Normal H,S,V: (0-360,0-100%,0-100%)
    # OpenCV H,S,V: (0-180,0-255 ,0-255)
    return (180 * h / 360, 255 * s / 100, 255 * v / 100)

Je kunt het bijvoorbeeld als volgt gebruiken:

im=cv2.imread("image.jpg",1)
im_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
color1 = fixHSVRange(h=10, s=20, v=0)
color2 = fixHSVRange(h=30, s=70, v=100)
mask = cv2.inRange(im_hsv, color1, color2)
cv2.imwrite("mask.jpg",mask)

Other episodes