Search code examples
pythonopencvcolor-space

OpenCV detection with different colorspace


I am using opencv to detect objects with cascade classifiers trained on grayscale images and then testing detection on different color spaces (images initially color) and calculating precision/recall/harmonic mean.
im wondering why i get the same results for greyscale and rgb but different in other colorspaces?

      # Read the image
    image = cv2.imread(imagePath)


    # convert to grayscale (default algorithm)
    if colorspace == "gray":
        colorCVT = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    elif colorspace == "hsv":
        colorCVT = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    elif colorspace == "hls":
        colorCVT = cv2.cvtColor(image, cv2.COLOR_BGR2HLS)
    elif colorspace == "lab":
        colorCVT = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
    elif colorspace == "luv":
        colorCVT = cv2.cvtColor(image, cv2.COLOR_BGR2LUV)
    elif colorspace == "yuv":
        colorCVT = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
    elif colorCVT --"rgb"
        colorspace = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    else:
        colorCVT = image

    print('using color mode: '+colorspace)

    with open(outputFilename, 'a') as results:
        results.write("Running detection on image:  "+imagePath +"\n")
        results.write("Detecting using trained classifier: "+cascadePath +"\n")
    # results.close()


    # training PARAMS
    SCALE_FACTOR = 1.02
    MIN_NEIGHBORS = 5
    MIN_SIZE = (10,10)
    MAX_SIZE = (128,128)

    # Detect objects in the image
    objects = trainedCascade.detectMultiScale(
        colorCVT,
        scaleFactor=SCALE_FACTOR,
        minNeighbors=MIN_NEIGHBORS,
        minSize=MIN_SIZE,
        maxSize=MAX_SIZE,
        flags = cv2.cv.CV_HAAR_SCALE_IMAGE
    )

Solution

  • If you look at the API for detectMultiScale, you will see that it expects the image to be grayscale. I assume that if it encounters a 3-channel image (be it BGR, HSV, or whatever), it tries to do a conversion to grayscale first.

    Unfortunately, when presented with a 3-channel image, OpenCV has no way of knowing which colorspace that image is using since there is no metadata to indicate such a thing. This limitation is apparent even in the cvtColor call where you have to specify both the source and the destination colorspaces. So in the case of a 3-channel image argument to detectMultiScale, it appears to always guess RGB (or maybe BGR? your code on BGR2RGB seems buggy) as the colorspace, and of course that is only correct if that is actually the colorspace.