cv2.imshow and numpy.dstack core dumped - python

I am trying to stack two images together, so i can show both in a single window.
First image is the original, 3-channel image, second one is a gray version.
I did the color conversion with cv2.cvtColor, transformed back to 3-channel with numpy.dstack,
and when i try cv2.imshow, it gives me a "core dumped" error.
Am i missing something? I need both images to have the same number of channels to stack them
with numpy.hstack. This happens on a Ubuntu 64bit machine.
import cv2
import numpy as np
img = cv2.imread("/home/bernie/Dropbox/Python/Opencv/lena512.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = np.dstack((gray,gray,gray))
#res = np.hstack((img,gray))
print gray.dtype
print gray.shape
cv2.imshow('gray',gray)
#cv2.imshow('res',res)
cv2.waitKey()
addition
On the other hand, using
gray = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)
in line 7 works without complaints, so i will stick to this for now. This means that there is a difference
between
the cv2.cvtColor result and numpy.dstack result for turning a 1-channel image to 3-channel with equal values.

As suggested in the comments, try using cv2.merge since apparently it's strided differently from np.dstack:
gray = cv2.merge([gray]*3)
See #fraxel's link for more info

Related

How possibly can I use the frames generated from my webcam to be the input of my Keras model?

I want to change the img_path to the frames generated from opencv:
img = image.load_img(img_path, target_size=(224, 224))
How can I rewrite it?
I am assuming that the image.load_img() function that you are using is the one from keras_utils package.
As it is noted in the documentation, load_img() accepts path to the image as the first parameter and returns:
Returns:
A PIL Image instance.
It is not mentioned in the question, but if you read the frames from the camera using opencv they should already be numpy arrays which you could to pass to your model. Of course you should resize them to (224,224) before (how to resize the image using opencv).
However, if you want to have the PIL images (to have the same type as the one returned by load_img()), you need to convert your opencv frames (numpy array) to PIL image. Follow this question and answer by #ZdaR to do this conversion:
import cv2
import numpy as np
from PIL import Image
img = cv2.imread("path/to/img.png")
# You may need to convert the color.
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img)
# For reversing the operation:
im_np = np.asarray(im_pil)

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()

Error when overlaying two images in OpenCV and or PIL

I've tried overlaying two images in openCV both in openCV and in PIL, but to no avail. I'm using a 1000x1000x3 array of np.zeros for the background (aka, a black background) and this random image of my monitor, but I really can't get it to work for some reason unbeknownst to me.
Trying with OpenCV only: (result(if you pay attention, you can see a couple of weird lines and dots in the middle))
base_temp = np.zeros((1000,1000,3))
foreground_temp = cv2.imread('exampleImageThatILinkedAbove.png')
base_temp[offset_y:offset_y+foreground_temp.shape[0], offset_x:offset_x+foreground_temp.shape[1]] = foreground_temp
Trying with PIL: (The result is literally the same as the OpenCV version)
base_temp = cv2.convertScaleAbs(self.base) #Convert to uint8 for cvtColor
base_temp = cv2.cvtColor(base_temp, cv2.COLOR_BGR2RGB) #PIL uses RGB and OpenCV uses BGR
base_temp = Image.fromarray(base_temp) #Convert to PIL Image
foreground_temp = cv2.cvtColor(cv2.convertScaleAbs(self.last_img), cv2.COLOR_BGR2RGB)
foreground_temp = Image.fromarray(foreground_temp)
base_temp.paste(foreground_temp, offset)
I'm using python3.5 and and OpenCV3.4 on Windows 10, if that's any help.
I'd like to avoid any solutions that require saving the cv2 images and then reloading them in another module to convert them but if it's unavoidable that's okay too. Any help would be appreciated!
If you check the type of base_temp, you will see it is float64 and that is going to cause you problems when you try to save it as a JPEG which expects unsigned 8-bit values.
So the solution is to create your base_temp image with the correct type:
base_temp = np.zeros((1000,1000,3), dtype=np.uint8)
The complete code and result look like this:
import cv2
import numpy as np
from PIL import Image
# Make black background - not square, so it shows up problems with swapped dimensions
base_temp=np.zeros((768,1024,3),dtype=np.uint8)
foreground_temp=cv2.imread('monitor.png')
# Paste with different x and y offsets so it is clear when indices are swapped
offset_y=80
offset_x=40
base_temp[offset_y:offset_y+foreground_temp.shape[0], offset_x:offset_x+foreground_temp.shape[1]] = foreground_temp
Image.fromarray(base_temp).save('result.png')

Why reading colored image as Gray Scale in OpenCv is different from convert same image from BGR to GRAY [duplicate]

I am working in opencv(2.4.11) python(2.7) and was playing around with gray images. I found an unusual behavior when loading image in gray scale mode and converting image from BGR to GRAY. Following is my experimental code:
import cv2
path = 'some/path/to/color/image.jpg'
# Load color image (BGR) and convert to gray
img = cv2.imread(path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Load in grayscale mode
img_gray_mode = cv2.imread(path, 0)
# diff = img_gray_mode - img_gray
diff = cv2.bitwise_xor(img_gray,img_gray_mode)
cv2.imshow('diff', diff)
cv2.waitKey()
When I viewed the difference image, I can see the left out pixels instead of jet black image. Can you suggest any reason? What is the correct way of working with gray images.
P.S. When I use both the images in SIFT, keypoints are different which may lead to different outcome specially when working with bad quality images.
Note: This is not a duplicate, because the OP is aware that the image from cv2.imread is in BGR format (unlike the suggested duplicate question that assumed it was RGB hence the provided answers only address that issue)
To illustrate, I've opened up this same color JPEG image:
once using the conversion
img = cv2.imread(path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
and another by loading it in gray scale mode
img_gray_mode = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
Like you've documented, the diff between the two images is not perfectly 0, I can see diff pixels in towards the left and the bottom
I've summed up the diff too to see
import numpy as np
np.sum(diff)
# I got 6143, on a 494 x 750 image
I tried all cv2.imread() modes
Among all the IMREAD_ modes for cv2.imread(), only IMREAD_COLOR and IMREAD_ANYCOLOR can be converted using COLOR_BGR2GRAY, and both of them gave me the same diff against the image opened in IMREAD_GRAYSCALE
The difference doesn't seem that big. My guess is comes from the differences in the numeric calculations in the two methods (loading grayscale vs conversion to grayscale)
Naturally what you want to avoid is fine tuning your code on a particular version of the image just to find out it was suboptimal for images coming from a different source.
In brief, let's not mix the versions and types in the processing pipeline.
So I'd keep the image sources homogenous, e.g. if you have capturing the image from a video camera in BGR, then I'd use BGR as the source, and do the BGR to grayscale conversion cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
Vice versa if my ultimate source is grayscale then I'd open the files and the video capture in gray scale cv2.imread(path, cv2.IMREAD_GRAYSCALE)

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