Finding red color in image using Python & OpenCV

前端 未结 3 1322
有刺的猬
有刺的猬 2020-12-02 14:26

I am trying to extract red color from an image. I have code that applies threshold to leave only values from specified range:

img=cv2.imread(\'img.bmp\')
img         


        
相关标签:
3条回答
  • 2020-12-02 15:05

    To detect red, you can use a HSV color thresholder script to determine the lower/upper thresholds then cv2.bitwise_and() to obtain the mask. Using this input image,

    We get this result and mask

    Code

    import numpy as np
    import cv2
    
    image = cv2.imread('1.jpg')
    result = image.copy()
    image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower = np.array([155,25,0])
    upper = np.array([179,255,255])
    mask = cv2.inRange(image, lower, upper)
    result = cv2.bitwise_and(result, result, mask=mask)
    
    cv2.imshow('mask', mask)
    cv2.imshow('result', result)
    cv2.waitKey()
    

    HSV color thresholder script with sliders, remember to change the image file path

    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()
    
    0 讨论(0)
  • 2020-12-02 15:08

    Play with this.

    #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()
    
    0 讨论(0)
  • 2020-12-02 15:15

    I would just add the masks together, and use np.where to mask the original image.

    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
    

    This should be much faster and much more readable than looping through each pixel of your image.

    0 讨论(0)
提交回复
热议问题