Python imread bug: "Unsupported BMP bitfields layout" - python

I seem to have encountered a bug in scipy.misc.imread, and I'm looking for a workaround. Here's a clip of the error report:
from scipy.misc import imread
im = imread('380.bmp')
...
C:\Anaconda3\lib\site-packages\PIL\BmpImagePlugin.py in _bitmap(self, header, offset)
145 raw_mode = MASK_MODES[(file_info['bits'], file_info['rgb_mask'])]
146 else:
--> 147 raise IOError("Unsupported BMP bitfields layout")
148 else:
149 raise IOError("Unsupported BMP bitfields layout")
OSError: Unsupported BMP bitfields layout
I can open the image without problems in an image viewer, so I'm sure it's not corrupted.
The main question is: What's the best alternative to imread, so I can get around this issue? Alternatively, if you know a way to fix imread, that would also be good.
By the way, I'm using Python 3.5.1 in Anaconda 2.4.1 (64 bit)

I had been facing the same error while using PIL.Image. I bypassed the issue using cv2.
My code is something like this:
import cv2 #pip install opencv-python
from PIL import Image #pip install pillow
temp_img = cv2.imread(filename.bmp)
color_corrected = cv2.cvtColor(temp_img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(color_corrected)
Best of luck.

I also got this same error while using PIL.Image.
This error message is a bit generic and there are a lot of possibilities of what went wrong, but in my case it was a bitmap that was in fact valid and therefore should have been supported. I filed an issue on PIL's Github and they agreed it was a bug and gave me a fix. See https://github.com/python-pillow/Pillow/issues/6435 .
Hopefully the fix will be released in a future version of PIL (>= 9.3.0).

Related

pylibdmtx library, try except not working - Assertion `value >= 0 && value < 256'

Question in short:
We have a specific png image, where searching the datamatrix codes on a given location with the help of pylibdmtx library. At that specified location (given xmin, ymin, xmax, ymax coordinates in the code), we crop the image, rescale and send to the library to decode. but getting assertion error from dmtxdecodescheme.c, and program halts. we wish to neglect the error (return "?????" if possible), but try/except not working, and no way to escape.
Details:
This kind of error had never happened before, only on this specific png image, and given specific coordinates & SCALER value.
Uploaded the image at: https://easyupload.io/3yioro , because i can't upload to stackoverflow due to size constraints (3.1 Mb is over the 2Mb limit)
if i crop or convert image to another extension, error doesn't reproduce. this is really a rare and hard to duplicate error.
here is the simplified code, where you search only 1 given location:
from pylibdmtx.pylibdmtx import decode as decoder
import cv2
xmin = 755
ymin = 501
xmax = 830
ymax = 576
squareDim=150
SCALER=2
def bruteDMSearch(croppedImage):
try:
barcode = decoder(croppedImage)
#brute force cv2.threshold
threshh=50
while((not barcode) and (threshh<250)):
threshh=threshh+15
ret, thresholdy = cv2.threshold(croppedImage, threshh, 255, cv2.THRESH_BINARY)
barcode=decoder(thresholdy)
if(barcode):
code = ((barcode[0])[0]).decode("utf-8")
return code
else:
return "??????"
except:
return "?????"
img = cv2.imread("img.png",0)
sheight=int(img.shape[0]/SCALER)
swidth=int(img.shape[1]/SCALER)
smaller_img=cv2.resize(img,(swidth,sheight))
croppy = smaller_img[ymin:ymax,xmin:xmax]
#cv2.imshow("croppy",croppy)
#cv2.waitKey(0)
code = bruteDMSearch(croppy)
output is:
python3: dmtxdecodescheme.c:115: PushOutputWord: Assertion `value >= 0 && value < 256' failed.
Aborted (core dumped)
Your code worked as-is for me.
I got this output
Initially I had other problems with libdmtx.(This is an issue with libdmtx I faced and has no issue with your Python code)
I installed libdmtx using condas in win10. But during runtime I got FileNotFoundError: Could not find module 'libdmtx-64.dll'
then I built the library from https://github.com/dmtx/libdmtx and got release mode dmtx.dll. renamed this dll to libdmtx-64.dll and placed in `C:\Users\balu\Miniconda3\Library\bin'.
Note: if QR decoding is your goal, check your old questions I have answered.
I managed to reproduce this issue on ubuntu 21.10 with libdmtx-dev 0.7.5-3 and pylibdmtx 0.1.9:
python: dmtxdecodescheme.c:128: PushOutputWord: Assertion `value >= 0 && value < 256' failed.
Aborted (core dumped)
Given that the library is written in C and the C module itself is throwing a segfault, the try-except logic will not help here. You will need to run this line:
barcode = decoder(croppedImage)
in a separate process (via subprocess or multiprocessing). Here is an example of how you'd use a decorator to run the decoder in a segfault-proof way via multiprocessing.

any existing code/library for image sharpness or blurriness estimation in python?

I would like to find some existing code/library for sharpness/blurriness estimation on normal images. (prefer in Python) I will need to compare the performance of different algorithms later.
I have 10000+ MRI scan images with different "quality"(sharpness/blurriness). I need to write code to filter images with certain "quality"(sharpness/blurriness) which is up to user. Hence, I am trying to research about image sharpness/blurriness estimation on medical images. My supervisor told me there are lots of existing code for sharpness/blurriness estimation on normal images(maybe it is no-reference sharpness metric) on internet. She asked me to search about them and try them on normal images first. Then try to learn about their algorithms.
I have searched about this on internet and found some pages which are relevant. However, lots of them are out of date.
For example:
On
Image sharpness metric
page,
Cumulative probability of blur detection (CPBD) https://ivulab.asu.edu/software/quality/cpbd
seems not working anymore. I guess the reason is that "imread" function is removed from new "scipy" library. (please see later code and error message) I think I can try the old version of "scipy" later. However, I would like to find some more currently available code/library about image sharpness/blurriness estimation.
Also, my working environment will be in Windows 10 or CentOS-7.
I have tried the following code with CPBD:
import sys, cpbd
from scipy import ndimage
input_image1 = ndimage.imread('D:\Work\Project\scripts\test_images\blur1.png', mode='L')
input_image2 = ndimage.imread('D:\Work\Project\scripts\test_images\clr1.png', mode='L')
print("blurry image sharpness:")
cpbd.compute(input_image1)
print("clear image sharpness:")
cpbd.compute(input_image2)
Error message from Python 3.7 shell (ran in Window 10):
Traceback (most recent call last):
File "D:\Work\Project\scripts\try_cpbd.py", line 1, in <module>
import sys, cpbd
File "D:\Program_Files_2\Python\lib\site-packages\cpbd\__init__.py", line 3, in <module>
from .compute import compute
File "D:\Program_Files_2\Python\lib\site-packages\cpbd\compute.py", line 14, in <module>
from scipy.misc import imread #Original: from scipy.ndimage import imread
ImportError: cannot import name 'imread' from 'scipy.misc' (D:\Program_Files_2\Python\lib\site-packages\scipy\misc\__init__.py)
Seems that cpbd package has not been updated from some time.
It worked for me with the following steps:
Edit "D:\Program_Files_2\Python\lib\site-packages\cpbd\compute.py":
Comment the last 4 lines starting with:
#if __name__ == '__main__':
Use the python code:
import cpbd
import cv2
input_image1 = cv2.imread('blur1.png')
if input_image1 is None:
print("error opening image")
exit()
input_image1 = cv2.cvtColor(input_image1, cv2.COLOR_BGR2GRAY)
print("blurry image sharpness:")
cpbd.compute(input_image1)
Since scipy.misc.imread is deprecated since 1.0.0, and removed in 1.2.0, I would use skimage.io.imread instead (which is in most ways a drop-in replacement).
Edit the code in cpbd/compute.py
import skimage.io
input_image1 = skimage.io.imread('blur1.png')
cv2 also works (or other options: imageio, PIL, ...) but skimage tends to be a bit easier to install/use.
The following steps worked for me:
Open the compute.py from C:\ProgramData\Anaconda3\Lib\site-packages\cpbd\compute.py or wherever you have installed it. You will find the following code:
from scipy.ndimage import imread
replace it with:
from skimage.io import imread
If you can't save the compute.py file, then copy it to desktop, edit it in the above mentioned way and replace the file in C:\ProgramData\Anaconda3\Lib\site-packages\cpbd\compute.py with it.
Following the answer from Baj Mile, I did the following and it worked for me.
opened the cpbd\compute.py file
commented the line : from scipy.ndimage import imread
Added the line: import cv2
Made the following changes to the main section:
if __name__ == '__main__':
#input_image = imread(argv[1], mode='L')
input_image=cv2.imread(argv[1])
sharpness = compute(input_image)
print('CPBD sharpness for %s: %f' % (argv[1], sharpness))
close the compute.py file.
In the main code:
import cpbd
import cv2
input_image1 = cv2.imread('testimage.jpg')
input_image1 = cv2.cvtColor(input_image1, cv2.COLOR_BGR2GRAY)
cpbd.compute(input_image1)

Overcome opencv CV_IO_MAX_IMAGE_PIXELS limitation in python

I'm trying to use opencv to open an image size 4864 x 382565 and it is bigger than CV_IO_MAX_IMAGE_PIXELS limitation which is 2^30 pixels.
img = cv2.cvtColor(cv2.imread(path),cv2.COLOR_BGR2GRAY)
You can do the trick of calling set CV_IO_MAX_IMAGE_PIXELS=18500000000 from the shell before running python script to bypass this check, but I wonder is there a better solution?
Thanks
I think I found the solution
os.environ["OPENCV_IO_MAX_IMAGE_PIXELS"] = pow(2,40).__str__()
import cv2 # import after setting OPENCV_IO_MAX_IMAGE_PIXELS
This will change the limitation to 2^40
Just remember to import opencv AFTER setting the environment variable, otherwise it wouldn't work

WinPython and OpenCV

I use WinPython to write my python programs. I need to solve the task of detecting faces in a video stream. I have installed opencv-python to WinPython using this command:
pip install opencv-python==3.4.0.12
When I run the following code, I get a False:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
ret, img = cap.read()
print(ret)
What I am doing wrong?
Seems like legit function result. As you can see, from documentation VideoCapture::read function returns retval and image, in case there was image to return. Apparently, "False" value of the ret variable in your code means that there was no image.
Edit:
I looked up documentation and here's what i've found:
"If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer."

opencv getImage() error

I wrapped opencv today with simplecv python interface. After going through the official SimpleCV Cookbook I was able to successfully Load, Save, and Manipulate images. Thus, I know the library is being loaded properly.
However, under the Using a Camera, Kinect, or Virtual Camera heading I was unsuccessful in running some commands. In particular, mycam = Camera() worked, but img = mycam.getImage() produced the following error:
In [35]: img = mycam.getImage().save()
OpenCV Error: Bad argument (Array should be CvMat or IplImage) in cvGetSize, file /home/jordan/OpenCV-2.2.0/modules/core/src/array.cpp, line 1237
---------------------------------------------------------------------------
error Traceback (most recent call last)
/home/simplecv/<ipython console> in <module>()
/usr/local/lib/python2.7/dist-packages/SimpleCV-1.1-py2.7.egg/SimpleCV/Camera.pyc in getImage(self)
332
333 frame = cv.RetrieveFrame(self.capture)
--> 334 newimg = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 3)
335 cv.Copy(frame, newimg)
336 return Image(newimg, self)
error: Array should be CvMat or IplImage
I'm running Ubuntu Natty on a HP TX2500 tablet. It has a built in webcam, (CyberLink Youcam?) Has anybody seen this error before? I've been all over the web today looking for a solution, but nothing seems to be doing the trick.
Update 1: I tested cv.QueryFrame(capture) using the code found here in a separate Stack Overflow question and it worked; so I've pretty much nailed this down to a webcam issue.
Update 2: In fact, I get the exact same errors on a machine that doesn't even have a webcam! It's looking like the TX2500 is not compatible...
since the error raised from Camera.py of SimpleCV, you need to debug the getImage() method. If you can edit it:
def getImage(self):
if (not self.threaded):
cv.GrabFrame(self.capture)
frame = cv.RetrieveFrame(self.capture)
import pdb # <-- add this line
pdb.set_trace() # <-- add this line
newimg = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 3)
cv.Copy(frame, newimg)
return Image(newimg, self)
then run your program, it will be paused as pdb.set_trace(), here you can inspect the type of frame, and try to figure out how get the size of frame.
Or you can do the capture in your code, and inspect the frame object:
mycam = Camera()
cv.GrabFrame(mycam.capture)
frame = cv.RetrieveFrame(mycam.capture)
To answer my own question...
I bought a Logitech C210 today and the problem disappeared.
I'm now getting warnings:
Corrupt JPEG data: X extraneous bytes before marker 0xYY.
However, I am able to successfully push a video stream to my web-browser via JpegStreamer(). If I cannot solve this error, I'll open a new thread.
Thus, for now, I'll blame the TX2500.
If anybody finds a fix in the future, please post.
Props to #HYRY for the investigation. Thanks.
I'm geting the camera with OpenCV
from opencv import cv
from opencv import highgui
from opencv import adaptors
def get_image()
cam = highgui.cvCreateCameraCapture(0)
im = highgui.cvQueryFrame(cam)
# Add the line below if you need it (Ubuntu 8.04+)
#im = opencv.cvGetMat(im)
return im
Anthony, one of the SimpleCV developers here.
Also instead of using image.save(), this function writes the file/video to disk, you instead probably want to use image.show(). You can save if you want, but you need to specify a file path like image.save("/tmp/blah.png")
So you want to do:
img = mycam.getImage()
img.show()
As for that model of camera I'm not sure if it works or not. I should note that we also wrapper different camera classes not just OpenCV, this is because OpenCV has a problem with webcams over 640x480, we now can do high resolution cameras.
Also I should mention, which I didn't realize, is that OpenCV less than 2.3 is broken with webcams on Ubuntu 11.04 and up. I didn't realize this as I was running Ubuntu 10.10 before, by the looks of your output you are using python 2.7 which makes me think you are on Ubuntu 11.04 or higher. Anyway, we have a fix for this problem. It is now pushed up into the master, it basically does a check to see if OpenCV is working, if not it will fall back to pygame.
This fix will also be in the 1.2 release of SimpleCV (It's in the master branch now)

Categories

Resources