问题
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
回答1:
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
, notPIL 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]
来源:https://stackoverflow.com/questions/65432742/cant-convert-image-to-grayscale-when-using-opencv