Displaying CR part of YCR_CB python opencv - python

I am trying to generate a colour space such that the red sections of a set of images are easily seen by converting it from BGR to YCR_CB using python and opencv like this:
img = cv2.imread(os.path.join(directory_to_cycle, filename), cv2.IMREAD_COLOR)
width, height = img.shape[0], img.shape[1]
img_yCrCb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
cv2.imshow('image', img_yCrCb[:,:,1])
but I am getting this error caused by cv2.imshow('image', img_yCrCb[:,:,1])
error: C:\slave\WinInstallerMegaPack\src\opencv\modules\core\src\array.cpp:2482: error: (-206) Unrecognized or unsupported array type
and I don't understand why since others that have used this exact code have it working
Does anyone have any ideas whether its to fix this problem or an alternative solution to what I am trying to do?

Related

OpenCV(4.2.0) (-206:Bad flag (parameter or structure field)) Unrecognized or unsupported array type in function 'cvGetMat'

i am trying to inpaint on a 8000x4000 image, and a 8000x4000 binary mask but getting the following error.
error Traceback (most recent call
last) in
1 img = cv.imread('input/200130_033344133.jpg')
2 mask = cv.imread('resources/maskX.png',0)
----> 3 dst = cv.inpaint(img,mask,3,cv.INPAINT_TELEA)
4 cv.imshow('dst',dst)
5 cv.waitKey(0)
error: OpenCV(4.2.0)
C:\projects\opencv-python\opencv\modules\core\src\array.cpp:2492:
error: (-206:Bad flag (parameter or structure field)) Unrecognized or
unsupported array type in function 'cvGetMat'
here is my code.
what i tried was to convert the image and the mask to numpy array or cv2.UMat. but all in vain
img = cv.imread('input/200130_033344133.jpg')
mask = cv.imread('resources/maskX.png',0)
dst = cv.inpaint(img,mask,3,cv.INPAINT_TELEA)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
any reason why its not working?
the images are loading properly i checked.
I do not know what is wrong, because it works fine for me on Python 3.7 and OpenCV 3.4 on Mac OSX.
Did you import cv? Is your mask more than 1 channel after making grayscale? Perhaps it is an issue with OpenCV 4?
Here is what works for me.
Image with scratch:
Scratch Mask:
import cv2
img = cv2.imread('zelda1_scratch.jpg')
mask = cv2.imread('zelda1_scratch_mask.png',0)
dst = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)
cv2.imwrite('zelda1_scratch_inpainted.jpg', dst)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
I had the same error while trying to inpaint.
error: (-206:Bad flag (parameter or structure field)) Unrecognized or unsupported array type in function 'cvGetMat'
Then I realised I typed the mask format incorrectly instead of .jpg I wrote .png. So cv2.imread() was loading an empty matrix. When I fixed typo, error was gone.
So please check again your input image and mask name and formats.
I think this error is the sign of that image cannot loaded correctly.
Sincerely,
Enes

How to determine the number of channels in image?

I want to see the number of channels for thermal images, RGB images, grayscale images and binary images.
So I write this program:
import cv2
import numpy
img = cv2.imread("B2DBy.jpg")
print('No of Channel is: ' + str(img.ndim))
cv2.imshow("Channel", img)
cv2.waitKey()
But it gives the same three channel results for all types of images? I've read this question but it gives an error:
img = cv2.imread("B2DBy.jpg", CV_LOAD_IMAGE_UNCHANGED)
NameError: name 'CV_LOAD_IMAGE_UNCHANGED' is not defined
So my question is: Is it is the right way to see the number of channels? Or, somehow, I entered three channel images all the time and thus it gives three channel output?
My inputs:
The correct parameter in your cv2.imread should be:
img = cv2.imread('path/to/your/image', cv2.IMREAD_UNCHANGED)
Let's have a look at your images now. I use ImageJ's Show Info... command as well as the following Python code with OpenCV and Pillow:
import cv2
from PIL import Image
img_pil = Image.open('path/to/your/image')
print('Pillow: ', img_pil.mode, img_pil.size)
img = cv2.imread('path/to/your/image', cv2.IMREAD_UNCHANGED)
print('OpenCV: ', img.shape)
First image (depth map)
Pillow: RGB (640, 512)
OpenCV: (512, 640, 3)
ImageJ also says, that's a RGB image. So, most likely, your depth map was just saved as a RGB png.
Second image (dog)
Pillow: RGB (332, 300)
OpenCV: (300, 332, 3)
Interestingly, ImageJ says, that's an grayscale jpg! I assume, OpenCV and Pillow just don't support grayscale jpg, although there seems to be a grayscale jpg format.
Third image (sign)
Pillow: 1 (200, 140)
OpenCV: (140, 200)
Both, Pillow and OpenCV say, that's a grayscale image, which is also supported by ImageJ. Furthermore, Pillow uses mode '1' here, which is reflected by the dithered look of the image.
Fourth image (colours)
Pillow: RGB (500, 333)
OpenCV: (333, 500, 3)
That's just some RGB image; ImageJ also says this.
Conclusion
Yes, most likely, most of your images may just be RGB images. Nevertheless, using cv2.IMREAD_UNCHANGED at least will properly identify grayscale png files. It's questionable, if grayscale jpg files are properly supported.
Hope that helps!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
OpenCV: 4.2.0
Pillow: 7.0.0
----------------------------------------
If image is grayscale you will need to set a flag, tuple returned contains only number of rows and columns.
So it is a good method to check if loaded image is grayscale or color image.
image = cv2.imread('gray.jpg', cv2.IMREAD_GRAYSCALE)
image.shape
If len(img.shape) gives you three, third element gives you number of channels.
I'm not sure if it'll work, but documentation says this:
cv.LoadImage(filename, iscolor=flag) with flags given. There's a flag "<0" that stands for "Return the loaded image as is (with alpha channel)".
I would try this:
img = cv2.imread("B2DBy.jpg",iscolor=<0)
or this
img = cv2.imread("B2DBy.jpg",iscolor=CV_LOAD_IMAGE_ANYDEPTH)

Laplacian opencv fails with cv2.error: OpenCV(4.1.2)

I am trying to apply laplacian to a median filter output to get a sharper image, by later processing. The code snippet is as below :
img = plt.imread('example.png')
img_res = cv.resize(img,(256,256))
gray_image = cv.cvtColor(img_res, cv.COLOR_BGR2GRAY)
median_img = median_filter(gray_image, 5)
# Calculate the Laplacian
lap_img = cv.Laplacian(median_img,cv.CV_64F)
The input image is a RGB medical image. I am faced with the following error, when running this code:
cv2.error: OpenCV(4.1.2) C:/projects/opencv-python/opencv/modules/imgproc/src/filter.simd.hpp:3175: error: (-213:The function/feature is not implemented) Unsupported combination of source format (=5), and destination format (=6) in function 'cv::opt_AVX2::getLinearFilter'
This error occurs for any image from the dataset. Could you please point out what could be the issue? The example is followed from this link for grayscale images.
Instead of using two different libraries (matplotlib and opencv), stick to using one library at a time while performing image-processing. The reason is because these two libraries use different formats to store images. matplotlib uses RGB convention while opencv uses BGR. My guess is that you're encountering this error due to using matplotlib to load the image, and then performing operations with opencv. Simply, loading the image using cv2.imread() instead of plt.imread() seems to fix the problem
Input -> Output
import cv2
from scipy.ndimage.filters import median_filter
import numpy as np
img = cv2.imread('1.png')
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
median_img = median_filter(gray_image, 5)
# Calculate the Laplacian
lap_img = cv2.Laplacian(median_img,cv2.CV_64F).astype(np.uint8)
cv2.imshow('lap_img', lap_img)
cv2.imwrite('lap_img.png', lap_img)
cv2.waitKey()

Cryptic OpenCv error

I am trying to detect humans in images using the haarcascade full body algorithm using OpenCv in Python.
when i consider using it on a single image, I face no issues.
import numpy as np
import cv2 as cv
body_cascade = cv.CascadeClassifier(r'...\haarcascade_fullbody.xml')
image = cv.imread(r'...\image.jpg')
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
body = body_cascade.detectMultiScale(gray, 1.01, 4)
for (x,y,w,h) in body:
cv.rectangle(image,(x,y),(x+w,y+h),(255,0,0),3)
But, when I try to use the same program and iterate over several images at once, I get a cryptic OpenCv error. I have some images in a folder and I want to separate images with humans in them from those that don't. I wrote the following:
import os
for file in os.walk(r'...\Folder'):
file=str(file)
im=cv.imread(file)
gray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
body = body_cascade.detectMultiScale(gray, 1.01, 4)
for (x,y,w,h) in body:
cv.rectangle(im,(x,y),(x+w,y+h),(255,0,0),3)
if(body.size >= 0):
print('okay')
else:
print('Not okay')
But I get the following error :
error: OpenCV(3.4.2) c:\projects\opencv-python\opencv\modules\imgproc\src\color.hpp:253: error: (-215:Assertion failed) VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function 'cv::CvtHelper<struct cv::Set<3,4,-1>,struct cv::Set<1,-1,-1>,struct cv::Set<0,2,5>,2>::CvtHelper'
for the line gray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
I am unable to understand what the error is and why the same code that works when taking individual images is working but not the case when iterating through a folder. Do I need to resize the images ?
Also, I tried with keeping just one image in the folder, on which the code had worked before, still doesn't work.
Doc, it seems like OpenCV fails to locate the image. What happens if you're using full paths instead of relative ones? (and what are the three dots there "..." ?)
please dump the file that you read back to disc for debugging purposes and I think you'll be surprised.

OpenCV Shows Gray Window

I'm trying to display an image using OpenCV. I have the following very basic code:
import cv2
img = cv2.imread('myimage.png', 0) # Reads a Gray-scale image
img2 = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.imshow("window", img2)
The window is opened properly, with the correct size, but it's gray - there's no image. The image is read properly (looking at both img and img2 in the debugger I see the expected values, not just one shade).
Note: Obviously I intend to do some image processing prior to showing the image, but first I need to be able to see the image...
OK, got it.
Turns out I needed to let OpenCV start handling events, it wasn't handling the WM_PAINT event. Adding cv2.waitKey() fixed this.
Sometimes the image size is high enough for imshow().
Try to resize the image by:
dimensions = (400,800)
image= cv2.imread('myimage.png', 0)
resized = cv2.resize(image, dimensions, interpolation = cv2.INTER_AREA)
cv2.imshow("window", resized )

Categories