I'm using cmake to build my project with opencv. There are two sub-projects, A and B, under the top directory. A has no opencv function while B uses VideoCapture to get image from webcam. There is no problem at first.
However, after I add the code from B to A, B can still capture image from webcam, but A cannot do the same thing, the error is below:
HIGHGUI ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV
VIDIOC_STREAMON: Inappropriate ioctl for device
It is strange, and I find that VideoCapture cannot get image in A, the code is below
VideoCapture cam;
cam.open(0);
if(!cam.isOpened()){
cout << "Failed to open webcam" << endl;
return false;
}
Mat Image;
cam >> Image;
if(Image.empty())
cout<<"Image empty"<<endl;
"Image empty" is always in console, which means it just cannot capture the image at all!!
I followed some suggestions such as install "v4l2ucp", but there is no folder under "/usr/lib/" named "libv4l", so LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so dose not work.
I will very appreciate it if someone could give me some help to solve the problem in project A.
The file might not necessarily be there. Try find / -name "*v4l1compat.so*" 2>/dev/null or find / -name "*libv4l*" 2>/dev/null. It should succeed since your project B captures frames just fine. Then try to export found file to LD_PRELOAD.
If it won't succeed - check out your libv4l installation.
And make sure you trying to open() the correct camera which is not already in use.
Related
I have a problem seemingly caused by OpenCV 3.xx - the problem does not manifest in OpenCV 2.xx
The issue is reading video files. I've set my code up as follows:
>#include <opencv2\opencv.hpp>
>#include <opencv2\core\core.hpp>
>#include <opencv2\highgui\highgui.hpp>
>#include <opencv2\imgproc\imgproc.hpp>
>#include <opencv2\features2d\features2d.hpp>
>int main()
> cv::VideoCapture cap;
> cv::Mat frame;
> if(!cap.open("Myfile.avi"))
> std::cout << "Open failed" << std::endl;
> else
> cap.read(frame);
>
> cv::imshow("Frame", frame);
> cv::waitKey(5000);
> return 0;
Now the problem is when the code gets to "cap.read(frame)" I get a "vector subscript is out of range" error with OpenCV 3.40 and this does not happen with my build of OpenCV 2.4.9. The format of the file is in avi, its not some weird codec, and clearly it works in previous versions of OpenCV.
I've tried other OpenCV 3.xx builds and I get the same or similar problems with simply reading a file in.
My question is twofold:
How do I get OpenCV 3.xx to work with reading video files (or do I need to regress to 2.xx?)
Why has the major revision change completely screwed up video file reading? That doesn't make any sense for a computer vision API.
As a guess it will be something to do with the FFMPEG implementation because various searches have turned up other people having issues with this.
Any help is much appreciated.
Thanks
I've managed to resolve it myself, it turns out that in OpenCV 3.xx I have to force the VideoCapture::open to use the FFMPEG library by doing this:
>cap.open("Myfile.avi", cv::CAP_FFMPEG)
where the latter parameter is the flags to identify which VideoCapture API backend to use. The list can be found here for any one else interested:
https://docs.opencv.org/3.3.0/d4/d15/group__videoio__flags__base.html
my goal is to capture a frame from a rtmp stream every second, and process it using OpenCV. I'm using FFmpeg version N-71899-g6ef3426 and OpenCV 2.4.9 with the Java interface (but I'm first experimenting with Python).
For the moment, I can only take the simple and dirty solution, which is to capture images using FFmpeg, store them in disk, and then read those images from my OpenCV program. This is the FFmpeg command I'm using:
ffmpeg -i "rtmp://antena3fms35livefs.fplive.net:1935/antena3fms35live-live/stream-lasexta_1 live=1" -r 1 capImage%03d.jpg
This is currently working for me, at least with this concrete rtmp source. Then I would need to read those images from my OpenCV program in a proper way. I have not actually implemented this part, because I'm trying to find a better solution.
I think the ideal way would be to capture the rtmp frames directly from OpenCV, but I cannot find the way to do it. This is the code in Python I'm using:
cv2.namedWindow("camCapture", cv2.CV_WINDOW_AUTOSIZE)
cap = cv2.VideoCapture()
cap.open('"rtmp://antena3fms35livefs.fplive.net:1935/antena3fms35live-live/stream-lasexta_1 live=1"')
if not cap.open:
print "Not open"
while (True):
err,img = cap.read()
if img and img.shape != (0,0):
cv2.imwrite("img1", img)
cv2.imshow("camCapture", img)
if err:
print err
break
cv2.waitKey(30)
Instead of read() function, I'm also trying with grab() and retrieve() functions without any good result. The read() function is being executed every time, but no "img" or "err" is received.
Is there any other way to do it? or maybe there is no way to get frames directly from OpenCV 2.4.9 from a stream like this?
I've read OpenCV uses FFmpeg to do this kind of tasks, but as you can see, in my case FFmpeg is able to get frames from the stream while OpenCV is not.
In the case I could not find the way to get the frames directly from OpenCV, my next idea is to pipe somehow, FFmpeg output to OpenCV, which seems harder to implement.
Any idea,
thank you!
UPDATE 1:
I'm in Windows 8.1. Since I was running the python script from Eclipse PyDev, this time I run it from cmd instead, and I'm getting the following warning:
warning: Error opening file (../../modules/highgui/src/cap_ffmpeg_impl.hpp:545)
This warning means, as far as I could read, that either the file-path is wrong, or either the codec is not supported. Now, the question is the same. Is OpenCV not capable of getting the frames from this source?
Actually I have spent more that one day to figure out how to solve this issue. Finally I have solved this problem with the help of this link.
Here is client side code.
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int, char**) {
cv::VideoCapture vcap;
cv::Mat image;
const std::string videoStreamAddress = "rtmp://192.168.173.1:1935/live/test.flv";
if(!vcap.open(videoStreamAddress)) {
std::cout << "Error opening video stream or file" << std::endl;
return -1;
}
cv::namedWindow("Output Window");
cv::Mat edges;
for(;;) {
if(!vcap.read(image)) {
std::cout << "No frame" << std::endl;
cv::waitKey();
}
cv::imshow("Output Window", image);
if(cv::waitKey(1) >= 0) break;
}
}
Note: In this case I have created a android application to get real time video and send it to rtmp server wowza which is deployed in PC.So that is where I created this c++ implementation for real time video processing.
python -c "import cv2; print(cv2.getBuildInformation())"
check build opencv with ffmpeg。If it is correct, your code should be fine。
If not, rebuild opencv with ffmpeg。
Under osx
brew install opencv --with-ffmpeg
I was using OpenCV to read the images from a folder. A lot of messages like this show up:
Corrupt JPEG data: premature end of data segment
Premature end of JPEG file
Premature end of JPEG file
Premature end of JPEG file
How to catch this exception and remove these image files?
Since you said you are reading 'images' (multiple images), you would be looping through files in the folder that you are reading them from.
In that case, if you check if the image is valid or not by using the following :
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
you can then proceed to deleting files which are corrupt/bad.
I've been struggling to find a solution too. Read tens of articles, most of which just state that openCV does not throw errors and only outputs the error on stderr.
Some suggest to use PIL, but that does not detect most of the image corruptions. Usually only premature end of file.
However the same errors that OpenCV warns about can be detected via imagemagick.
Install imagemagick (https://imagemagick.org/)
Make sure you have it in the path.
Put the following sub into your code and call it to verify a file from wherever you need to. It also outputs errors to stderr, however it raises an error (thanks to "-regard-warnings")
import subprocess
def checkFile(imageFile):
try:
subprocess.run(["identify", "-regard-warnings", imageFile]).check_returncode()
return true
except (subprocess.CalledProcessError) as e:
return false
If you don't want the check to spam your outputs, add stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL params to the run function call.
On windows if you have not installed the legacy commands use the new syntax:
subprocess.run(["magick", "identify", "-regard-warnings", imageFile]).check_returncode()
In opencv 2.4.6. I am trying to load a mat image file with a simple code given below. But the image is not loaded as I print the image size, it is showing '0'. Can anybody please tell me , what is going wrong?
int main(int argc, char argv[])
{
Mat a=imread("C:/image3.jpg");
cv::Size frame11_size = a.size();
printf("%d",frame11_size.height);
return 0;
}
Update: I solved the problem. The problem was, I was only including all the library,include and additional dependencies in 'debug mode' only. I did not change anything in 'release mode'. When I change the properties in 'release mode' as-well, it worked. thanks all for your kind responses, I am giving '+1' for your answers.
I think there should be single slash on your image path, and always check whether image is successfully loaded.
Mat a=imread("C:/image3.jpg");
if(! a.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
OpenCV can't open jpg files by itself. It depends on third parties to do so. Maybe you are missing certain dlls, or maybe your OpenCV installation don't have the right path to them. To test this assumption store your image in other formats. For example pgm or ppm. Those formats does not perform any encoding and just store image buffer in file as is. As a result OpenCV will not need any external libraries to open image in ppm format.
Recently I migrated to OpenCV 2.4.3 from OpenCV 2.4.1.
My program which worked well with 2.4.1 version now encounters problem with 2.4.3.
The problem is related to VideoCapture that can not open my video file.
I saw a similar problem while searching the internet, but I couldn't find a proper solution for this. Here is my sample code:
VideoCapture video(argv[1]);
while(video.grab())
{
video.retrieve(imgFrame);
imshow("Video",ImgFrame);
waitKey(1);
}
It's worth mentioning that capturing video from webcam device works well, but I want to grab stream from file.
I'm using QT Creator 5 and I compiled OpenCV with MinGW. I'm using Windows.
I tried several different video formats and I rebuilt OpenCV with and without ffmpeg, but the problem still persists.
Any idea how to solve the problem?
Try this:
VideoCapture video(argv[1]);
int delay = 1000.0/video.get(CV_CAP_PROP_FPS);
while(1)
{
if ( !video.read(ImgFrame)) break;
imshow("Video",ImgFrame);
waitKey(delay);
}
In my experience with OpenCV I struggled using IP cams until my mentor discovered how to get them to work, don't forget to plug your IP address in otherwise it won't work!
import cv2
import numpy as np
import urllib.request
# Sets up the webcam and connects to it and initalizes a variable we use for it
stream=urllib.request.urlopen('http://xx.x.x.xx/mjpg/video.mjpg')
bytes=b''
while True:
# Takes frames from the camera that we can use
bytes+=stream.read(16384)
a = bytes.find(b'\xff\xd8')
b = bytes.find(b'\xff\xd9')
if a!=-1 and b!=-1:
jpg = bytes[a:b+2]
bytes= bytes[b+2:]
frame = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.IMREAD_COLOR)
img = frame[0:400, 0:640] # Camera dimensions [0:WIDTH, 0:HEIGHT]
# Displays the final product
cv2.imshow('frame',frame)
cv2.imshow('img',img)
# Hit esc to kill
if cv2.waitKey(1) ==27:
exit(0)