mchd
mchd

Reputation: 3163

Can't convert image to grayscale when using OpenCV

I have a transparent logo that I want to convert to grayscale using OpenCV. I am using the following code

def to_grayscale(logo):
    gray = cv2.cvtColor(logo, cv2.COLOR_RGB2GRAY)
    blur = cv2.GaussianBlur(gray, (5, 5), 0)
    canny = cv2.Canny(blur, 50, 150)  # sick
    return canny

This is the image variable:

brand_logo = Image.open(current_dir + '/logos/' + logo_image, 'r').convert('RGBA')
brand_logo = to_grayscale(brand_logo)

And this is the error:

TypeError: Expected Ptr<cv::UMat> for argument 'src'

I tried to use .convert('L') from PIL but it makes it 90% transparent gray. Anyway I can fix this issue?

Update

def to_grayscale(logo):
    OCVim = np.array(logo)
    BGRim = cv2.cvtColor(OCVim, cv2.COLOR_RGB2BGR)
    blurry = cv2.GaussianBlur(BGRim, (5, 5), 0)
    canny = cv2.Canny(blurry, 50, 150)
    PILim = Image.fromarray(canny)
    return PILim

enter image description here

Upvotes: 0

Views: 1069

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207863

You are mixing OpenCV and PIL/Pillow unnecessarily and will confuse yourself. If you open an image with PIL, you will get a PIL Image which is doubly no use for OpenCV because:

  • OpenCV expects Numpy arrays, not PIL Images, and
  • OpenCV uses BGR ordering, not RGB ordering like PIL uses.

The same applies when saving images.

There are three possible solutions:

  • stick to PIL
  • stick to OpenCV
  • convert every time you move between the two packages.

To convert from PIL Image to OpenCV's Numpy array:

OCVim = np.array(PILim)

To convert from OpenCV's Numpy array to PIL Image:

PILim = Image.fromarray(OCVim)

To reverse the colour ordering, not necessary with greyscale obviously, either use:

BGRim = cv2.cvtColor(RGBim, cv2.COLOR_RGB2BGR)

or use a negative Numpy stride:

BGRim = RGBim[..., ::-1]

Upvotes: 3

Related Questions