How can I write a cv2 / Pillow-modified image out to disk? - python

I have an image opened with Image.open(). I make some changes, reassigning pixel RGV values,and try to save.
When I try to save, I get:
Trace back (most recent call last):
File "./shimmer", line 97, in <module>
cv2.imwrite('/home/christos/portrait-out.jpg', result)
TypeError: Expected Pre<cv::UMat> for argument 'img'
This happens when the image has been created, baseline = Image.open('/home/christos/portrait-new-mini.jpg').
In searching I have found similar reported errors but no clear articulation of "Here’s what works and how’s why."
I have also seen pages in which similar work is done without similar recorded difficulties.
I can post my code if that is requested, but I am guessing that the problem is narrowly defined by the cv2.imwrite() call and something I want to be feeding the invocation.

Seems that you open the Image in Pillow and try to save the Pillow Image with OpenCV. OpenCV expect a numpy array. You should first convert your image before write in file with opencv.
Check this post : https://stackoverflow.com/a/14140796/13103631
I think, it will solve your issue

Related

matplotlib PIL reading tif - ValueError: tile cannot extend outside image

I would like to read a tif file with basically the following code:
import matplotlib.pyplot as plt
filename = 'test.tif'
plt.imread(filename)
This results in the following error message (just the last lines):
File ".../miniconda2/lib/python2.7/site-packages/PIL/Image.py", line 692, in tobytes
self.load()
File ".../miniconda2/lib/python2.7/site-packages/PIL/TiffImagePlugin.py", line 1013, in load
return super(TiffImageFile, self).load()
File ".../miniconda2/lib/python2.7/site-packages/PIL/ImageFile.py", line 204, in load
decoder.setimage(self.im, extents)
ValueError: tile cannot extend outside image
When I open the tif image with imagemagick's display and save it without making changes, everything works normally.
Nevertheless, I think it could a problem with my python environment/version, as my colleague who's working with the same code and the same files did not have this problem.
I tried many files and it ends in the same for all of them. I am aware that, for this mini example, I could make a workaround or use e.g. gdal (which works fine). But as these lines are just a part of a larger code and are supposed to work for new files immediately, I would like to have a real solution.
I am working with openSUSE 11.4, conda 4.3.23, Python 2.7.13, matplotlib 2.0.2 .
This could be a duplicate of Value Error in reading tif image with pil in python?. Due to the lack of specific information there, I open a new question. Sorry if that's the wrong way - my first post here...
Remark: I see that my tif file gets uploaded as png here. Is there a way to change that?

Why isn't imread in openCV opening some of the images?

The error im getting is
"Traceback (most recent call last): File
"C:\Users\harit\Desktop\red.py", line 6, in
cv2.imshow('img',img) error: C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:304:
error: (-215) size.width>0 && size.height>0 in function cv::imshow"
The relevant code is this:
import cv2
import numpy as np
img = cv2.imread('C:\Users\harit\Desktop\images\12.jpg')
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Try changing
img = cv2.imread('C:\Users\harit\Desktop\images\12.jpg')
to
img = cv2.imread(r'C:\Users\harit\Desktop\images\12.jpg')
Backslash is an escape character, and the r before the quotes tells python to "ignore" them.
For example:
>>> s = 'C:\Users\harit\Desktop\images\12.jpg'
>>> print s
C:\Users\harit\Desktop\images
.jpg
This is the wrong path!... with an 'r' in front of the string:
>>> s = r'C:\Users\harit\Desktop\images\12.jpg'
>>> print s
C:\Users\harit\Desktop\images\12.jpg
See https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals for more on raw strings
I think I kind of understand the problem. Maybe I am wrong with my solution. When I first encountered this problem I thought that open cv only accepts png images instead of jpg however, even after converting the image into an png it still did not make the problem go away. Later on, I tried to rename the name of the image and the new name started with a letter instead of a number and it worked. So, maybe python open cv can't read files with names starting with a number like it cannot accept any variable names that start with numbers. Maybe I am totally wrong, but renaming the image file made the problem go away.

OpenCV Python not opening images with imread()

I'm not entirely sure why this is happening but I am in the process of making a program and I am having tons of issues trying to get opencv to open images using imread. I keep getting errors saying that the image is 0px wide by 0px high. This isn't making much sense to me so I searched around on here and I'm not getting any answers from SO either.
I have taken about 20 pictures and they are all using the same device. Probably 8 of them actually open and work correctly, the rest don't. They aren't corrupted either because they open in other programs. I have triple checked the paths and they are using full paths.
Is anyone else having issues like this? All of my files are .jpgs and I am not seeing any problems on my end. Is this a bug or am I doing something wrong?
Here is a snippet of the code that I am using that is reproducing the error on my end.
imgloc = "F:\Kyle\Desktop\Coinjar\Test images\ten.png"
img = cv2.imread(imgloc)
cv2.imshow('img',img)
When I change the file I just adjust the name of the file itself the entire path doesn't change it just refuses to accept some of my images which are essentially the same ones.
I am getting this error from a later part of the code where I try to use img.shape
Traceback (most recent call last):
File "F:\Kyle\Desktop\Coinjar\CoinJar Test2.py", line 14, in <module>
height, width, depth = img.shape
AttributeError: 'NoneType' object has no attribute 'shape'
and I am getting this error when I try to show a window from the code snippet above.
Traceback (most recent call last):
File "F:\Kyle\Desktop\Coinjar\CoinJar Test2.py", line 11, in <module>
cv2.imshow('img',img)
error: ..\..\..\..\opencv\modules\highgui\src\window.cpp:261: error: (-215) size.width>0 && size.height>0 in function cv::imshow
Probably you have problem with special meaning of \ in text - like \t or \n
Use \\ in place of \
imgloc = "F:\\Kyle\\Desktop\\Coinjar\\Test images\\ten.png"
or use prefix r'' (and it will treat it as raw text without special codes)
imgloc = r"F:\Kyle\Desktop\Coinjar\Test images\ten.png"
EDIT:
Some modules accept even / like in Linux path
imgloc = "F:/Kyle/Desktop/Coinjar/Test images/ten.png"
From my experience, file paths that are too long (OS dependent) can also cause cv2.imread() to fail.
Also, when it does fail, it often fails silently, so it is hard to even realize that it failed, and usually something further the the code will be what sparks the error.
Hope this helps.
Faced the same problem on Windows: cv.imread returned None when reading jpg files from a subfolder. The same code and folder structure worked on Linux.
Found out that cv.imread processes the same jpg files, if they are in the same folder as the python file.
My workaround:
copy the image file to the python file folder
use this file in cv.imread
remove redundant image file
import os
import shutil
import cv2 as cv
image_dir = os.path.join('path', 'to', 'image')
image_filename = 'image.jpg'
full_image_path = os.path.join(image_dir, image_filename)
image = cv.imread(full_image_path)
if image is None:
shutil.copy(full_image_path, image_filename)
image = cv.imread(image_filename)
os.remove(image_filename)
...
I had i lot of trouble with cv.imread() not finding my Image. I think i tryed everything involving changing the path. The os.path.exists(file_path) function also gave me back a True.
I finaly solved the problem by loading the images with imageio.
img = imageio.imread('file_path')
This also loads the img in a numpy array and you can use funktions like cv.matchTemplate() on this object. But i would recomment if u are doing stuff with multiple images that you then read all of them with imageio because i found diffrences in the arrays produced by .imread() from the two libs (opencv, imageio) on a File both of them could open.
I hope i could help someone
Take care to :
try imread() with a reliable picture,
and the correct path in your context like (see Kyle772 answer). For me either //or \.
I lost a couple of hours trying with 2 images saved from a left click in a browser. As soon as I took a personal camera image, it works fine.
Spyder screen shot
#context windows10 / anaconda / python 3.2.0
import cv2
print(cv2.__version__) # 3.2.0
imgloc = "D:/violettes/Software/Central/test.jpg" #this path works fine.
# imgloc = "D:\\violettes\\Software\\Central\\test.jpg" this path works fine also.
#imgloc = "D:\violettes\Software\Central\test.jpg" #this path fails.
img = cv2.imread(imgloc)
height, width, channels = img.shape
print (height, width, channels)
python opencv image-loading imread
I know that the question is already answered but in case anybody still is not able to load images with imread. It may be because there are letters in the string path witch imread does not accept.
For exmaple umlauts and diacritical marks.
My suggestion for everyone facing the same problem is to try this:
cv2.imshow("image", img)
The img is keyword. Never forget.
When you get error like this AttributeError: 'NoneType' object has no attribute 'shape'
Try with new_image=image.copy

PIL: How to reopen an image after verifying?

I need open an image, verify the image, then reopen it (see last sentence of below quote from PIL docs)
im.verify()
Attempts to determine if the file is broken, without actually decoding
the image data. If this method finds any problems, it raises suitable
exceptions. This method only works on a newly opened image; if the
image has already been loaded, the result is undefined. Also, if you
need to load the image after using this method, you must reopen the
image file.
This is what I have in my code, where picture is a django InMemoryUploadedFile object:
img = Image.open(picture)
img.verify()
img = Image.open(picture)
The first two lines work fine, but I get the following error for the third line (where I'm attempting to "reopen" the image):
IOError: cannot identify image file
What is the proper way to reopen the image file, as the docs suggest?
This is no different than doing
f = open('x.png')
Image.open(f)
Image.open(f)
The code above does not work because PIL advances in the file while reading its first few bytes to (attempt to) identify its format. Trying to use a second Image.open in this situation will fail as noted because now the current position in the file is past its image's header. To confirm this, you can verify what f.tell() returns. To solve this issue you have to go back to the start of the file either by doing f.seek(0) between the two calls to Image.open, or closing and reopening the file.
Try doing a del img between the verify and second open.

Unrecognized or unsupported array type in function cvGetMat in python opencv

I am trying to code in python opencv-2.4.3, It is giving me an error as below
Traceback (most recent call last):
File "/home/OpenCV-2.4.3/cam_try.py", line 6, in <module>
cv2.imshow('video test',im)
error: /home/OpenCV-2.4.3/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat
I am not understanding what does that mean, Can anybody help me out?
Thankyou.
The relevant snippet of the error message is Unrecognized or unsupported array type in function cvGetMat. The cvGetMat() function converts arrays into a Mat. A Mat is the matrix data type that OpenCV uses in the world of C/C++ (Note: the Python OpenCV interface you are utilizing uses Numpy arrays, which are then converted behind the scenes into Mat arrays). With that background in mind, the problem appears to be that that the array im you're passing to cv2.imshow() is poorly formed. Two ideas:
This could be caused by quirky behavior on your webcam... on some cameras null frames are returned from time to time. Before you pass the im array to imshow(), try ensuring that it is not null.
If the error occurs on every frame, then eliminate some of the processing that you are doing and call cv2.imshow() immediately after you grab the frame from the webcam. If that still doesn't work, then you'll know it's a problem with your webcam. Else, add back your processing line by line until you isolate the problem. For example, start with this:
while True:
# Grab frame from webcam
retVal, image = capture.read(); # note: ignore retVal
# faces = cascade.detectMultiScale(image, scaleFactor=1.2, minNeighbors=2, minSize=(100,100),flags=cv.CV_HAAR_DO_CANNY_PRUNING);
# Draw rectangles on image, and then show it
# for (x,y,w,h) in faces:
# cv2.rectangle(image, (x,y), (x+w,y+h), 255)
cv2.imshow("Video", image)
i += 1;
source: Related Question: OpenCV C++ Video Capture does not seem to work
I was having the same error, and after about an hour of searching for the error, I found the path to the image to be improperly defined. It solved my problem, may be it will solve yours.
I solved the porblem by using a BGR-picture. the one from my cam was YUYV by default!
I am working in Windows with Opencv 2.3.1 and Python 2.7.2, so, I had the same problem, I solved it pasting the following DLL files: opencv_ffmpeg.dll and opencv_ffmpeg_64.dll in the installation folder of Python. Maybe it help you with a similar solution in Ubuntu.
For me, like Gab Hum did, I copied opencv_ffmpeg245.dll to my python code folder. Then it works.
Check your Image Array (or NpArray),(by printing it) whether you are trying to pass an array of images at one shot instead of passing each image at once.
A single image array would look like :
[[[ 76 85 103] ... [ 76 85 103]], ... ]
Rows encloses each columns, each matrix(pixes) encloses no of rows, each image comprises of matrices (pixels).
It is always good to have a sanity check, to be sure your camera is working.
In my case my camera is
raspistill -o test.jpg

Categories

Resources