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.
Related
The Problem
I have a problem when I am trying to automate a CNN Canny Edge detection pipeline, where many files are given as input and each is run through the Canny Edge detection CNN algorithm.
Here is the code that runs the algorithm on each given image (tiffs are in a folder, each should be processed using the CNN Canny algorithm):
files = get_files(TIF_DIR)
for f in files:
get_edges(f, OUT_DIR)
The code successfully processes one image, but subsequent attempts to process other images produces the error:
OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(4.0.1) Error: Bad argument (Layer "crop" already was registered) in cv::dnn::dnn4_v20181221::LayerFactory::registerLayer, file C:\ci\opencv-suite_1573470242804\work\modules\dnn\src\dnn.cpp, line 3629
This is the function that I believe the error comes from. I have tried:
making the three lines under 'setting up the layer' only run the first time the function is called, but the error persists.
Using cv.dnn_unregisterLayer('Crop'), but the problem persists with the same error
Renaming the Layer that I'm adding from 'Crop' to 'test', but the error stays the same. This leads me to think that it may not be the layer that I am manually adding that is the problem.
def get_edges(infile, outfolder):
head_tail = os.path.split(infile)
outpath = os.path.join(OUT_DIR, head_tail[1][:-3] + "_edge.png")
if os.path.isfile(outpath):
return 0
cap = cv.VideoCapture(infile)
hasFrame, frame = cap.read()
# Setting up layer
cv.dnn_registerLayer('Crop', CropLayer)
net = cv.dnn.readNet(os.path.abspath('deploy.prototxt'), os.path.abspath('hed_pretrained_bsds.caffemodel'))
inp = cv.dnn.blobFromImage(frame, scalefactor = 1.0, crop = False)
# Outputting from net...
net.setInput(inp)
out = net.forward()
out = out[0, 0]
out = 255 * out
out = out.astype(np.uint8)
cv.imwrite(outpath, out)
Thanks for your help!
Specifications:
Python version 3.8.5
OpenCV version 4.0.1
Windows 10.0.19042
I am an "advanced beginner" in Python, but a relative newbie with the Raspberry Pi...
What I'm trying to do:
I'm trying to capture a frame from the RTSP stream from a Wyze Cam V2 and save the image to a file. My code works - most of the time. But sometimes it fails for long periods of time. After much experimentation and trial and error I have determined that it is more likely to fail when the camera is in the dark! This seems very consistent.
My Code:
This is not the code from my actual project - it is the code I have been using to troubleshoot.
import cv2
import imageio
class Camera:
def __init__(self, ipaddress):
self.ipaddress = ipaddress
print("About to create VideoStream")
self.vs = cv2.VideoCapture(ipaddress, cv2.CAP_FFMPEG)
self.vs.set(cv2.CAP_PROP_BUFFERSIZE, 3)
if self.vs.isOpened():
print("Successfully created")
self.vs.release()
else:
print("Unable to create")
def capture(self):
self.vs.open(self.ipaddress)
success, frame = self.vs.read()
self.vs.release()
if success:
print("Capture Success")
return frame
else:
print("Failed to capture")
print("VideoCapture isOpen is " + str(self.vs.isOpened()))
return None
def is_opened(self):
return self.vs.isOpened()
# In actual code CAMNAME is the camera's name, PASSWORD is the password
# and XXX.XXX.X.XXX is the ip address
camera = Camera("rtsp://CAMNAME:PASSWORD#XXX.XXX.X.XXX/live")
leave = False
while not leave:
frame = camera.capture()
if frame is None:
print("Frame is none")
print("VideoCapture isOpen is " + str(camera.is_opened()))
else:
print("Successful capture - writing to file")
frame_color = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
imageio.imwrite("test.jpg", frame_color)
response = input("Capture again? ")
if len(response) == 0:
response = "y"
if response[0] == 'n':
leave = True
What I Have Tried:
The code works fine when run on Windows 10. So not directly a problem with the code. In fact, when the Pi is having trouble capturing, doing it at the same time on Windows works. So definitely the issue is the Pi interacting with OpenCV or the camera.
Since I had ++ trouble installing OpenCV:
I have tried re-installing it on a fresh install of the OS with PIP (sudo pip install opencv-contrib-python==4.1.0.25).
I tried to build OpenCV from scratch - took 2.5 days and failed miserably - likely I screwed up somewhere in the process, but don't feel like spending another 2 days doing this.
Finally I downloaded a Raspbian image with OpenCV pre-compiled (https://medium.com/#aadeshshah/pre-installed-and-pre-configured-raspbian-with-opencv-4-1-0-for-raspberry-pi-3-model-b-b-9c307b9a993a). All these install methods resulted in the same issues...
I have tried opening the VideoCapture without specifying cv2.CAP_FFMPEG. I feel like it was more reliable with this option.
I have tried leaving out the change in BUFFERSIZE. I'm not sure this line of code has any effect.
What I am Using:
Raspberry Pi Model B, Rev 2, 512 kb
Raspbian Stretch - though I have had the same issues with Buster.
Wyze Cam II "beta" firmware that provides RTSP support.
Python3
OpenCV 4.1.0 (cv2.version)
What happens:
I have been troubleshooting this intermittent problem for some time, and just today realized it always works with the garage (where the camera is located) is light, and fails when it is dark. (Which made the late night troubleshooting sessions so frustrating!)
I have had many problems in the past, but now the issue seems to be that if the garage (where the camera is located) is dark, the VideoCapture object will not be created (.isOpened() == False) or the read() method will return False, None.
I used to have a problem with read() returning an old image. I can tell it is old because the camera timestamps the captures. This is why I am always opening and closing the VideoCapture - I would rather it not return an image than return the wrong/old image.
In the past, with slightly different settings, I would get warnings on the screen either during the creation of the VideoCapture object, or during the read() command. These are usually along the lines of "[h264 # 0x1ea1780] error while decoding MB 78 67, bytestream -15". I have gotten different warnings but I don't have examples right now. If I get a warning, I often get a bad image.
I have also gotten images that are distorted - that bottom of the image (sometimes a few lines, sometimes more than half of the image) looks like it it is the same line of data over and over.
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).
Hi I'm new to opencv(version 2.4.7) and using it in python 2.7.4. I always get this error
HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP
whenever I use the command
cam = cv2.VideoCapture(cam_id)
The code works fine otherwise even with the error. I'm trying to use this wireless camera and it shows an image which has a magenta and green colored grid structure. My question is why am I getting the error and this weird image. The code gives nice image on other system also on my system itself. gstreamer-properties also have clear picture. The code:
from cv2 import cv
import cv2
import sys
def main():
cam_id = 0
# parameter
for i, arg in enumerate( sys.argv ):
if i == 0: continue
else: cam_id = arg
cam = cv2.VideoCapture(cam_id)
cv2.namedWindow("window", cv.CV_WINDOW_AUTOSIZE)
running = True
while running:
try:
flag, img = cam.read()
if flag:
cv2.imshow("window", img)
cv2.waitKey(30)
except KeyboardInterrupt:
running = False
cv2.destroyWindow("window")
main()
Sorry to update so late, I had figured out solution of the issue long ago but forgot to answer it here. It required loading a library before running the code. Use of following commands should do the trick.
For 32bit system:
$ LD_PRELOAD=/usr/lib/i386-linux-gnu/libv4l/v4l2convert.so python filename.py
For 64bit system:
$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libv4l/v4l2convert.so python filename.py
If this doesn't work then try locating the file v4l2convert.so by using command,
$ locate v4l2convert.so
As the output you'll see different paths, now try LD_PRELOAD with different paths.
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)