Closed gworkman closed 8 months ago
Hi @gworkman, thanks for reporting this issue! I've fix it in https://github.com/cocoa-xu/evision/commit/62f60d6bd1975f09ba36f5e2d471275c2a57a341, and I'll release v0.1.38 soon.
But sadly I found that this function only supports the V4L (Video 4 Linux) video backend when I test it on my Mac. So you may have to use Linux if you really want to use this function.
iex> video = Evision.VideoCapture.videoCapture("test_video.mp4")
%Evision.VideoCapture{
fps: 29.97002997002997,
frame_count: 815.0,
frame_width: 1280.0,
frame_height: 720.0,
isOpened: true,
ref: #Reference<0.2140648639.4142530584.6526>
}
iex> Evision.VideoCapture.waitAny([video])
{:error,
"OpenCV(4.9.0) /Users/cocoa/Workspace/Git/evision/3rd_party/opencv/opencv-4.9.0/modules/videoio/src/cap.cpp:519: error: (-213:The function/feature is not implemented) VideoCapture::waitAny() is supported by V4L backend only in function 'waitAny'\n"}
v0.1.38 is shipped :)
Thanks Cocoa!
I was able to test it recently, and I ran into a little bit of an error. I think I have cameras with a bad firmware - they don't like to work when both of them are plugged into the device at the same time. What that looks like for Evision is that my calls to VideoCapture.read(camera1)
will sometimes for a long time before returning false
, as shown below
I'm hoping to use waitAny
to mitigate that behavior, but now with the following error messages I'm wondering if this is Evision, or something further down the V4L2 stack. Posting this here to see what you think :)
Thanks!
iex(1)> cam1 = Evision.VideoCapture.videoCapture(0)
%Evision.VideoCapture{
fps: 30.0,
frame_count: -1.0,
frame_width: 640.0,
frame_height: 480.0,
isOpened: true,
ref: #Reference<0.617984166.806223880.84111>
}
iex(2)> Evision.VideoCapture.read(cam1)
%Evision.Mat{
channels: 3,
dims: 2,
type: {:u, 8},
raw_type: 16,
shape: {480, 640, 3},
ref: #Reference<0.617984166.806223887.84378>
}
iex(3)> cam2 = Evision.VideoCapture.videoCapture(2)
%Evision.VideoCapture{
fps: 30.0,
frame_count: -1.0,
frame_width: 640.0,
frame_height: 480.0,
isOpened: true,
ref: #Reference<0.617984166.806223880.84112>
}
iex(4)> Evision.VideoCapture.read(cam2)
false
iex(5)> Evision.VideoCapture.waitAny([cam1, cam2], timeoutNs: 100)
{:error,
"OpenCV(4.9.0) /home/runner/work/evision/evision/3rd_party/opencv/opencv-4.9.0/modules/videoio/src/cap_v4l.cpp:2447: error: (-215:Assertion failed) ptr->havePendingFrame in function 'VideoCapture_V4L_waitAny'\n"}
iex(6)> Evision.VideoCapture.waitAny([cam1], timeoutNs: 100)
[0]
iex(7)> Evision.VideoCapture.waitAny([cam2], timeoutNs: 100)
{:error,
"OpenCV(4.9.0) /home/runner/work/evision/evision/3rd_party/opencv/opencv-4.9.0/modules/videoio/src/cap_v4l.cpp:2447: error: (-215:Assertion failed) ptr->havePendingFrame in function 'VideoCapture_V4L_waitAny'\n"}
Basically, anytime the misbehaving camera is in the waitAny
array, it will throw an error instead of returning an index of a camera with valid frames.
Hi @gworkman, I think this is probably an issue either in the V4L2 backend or the camera firmware(or drivers maybe?). I wonder if you could try the equivalent code using opencv-python
and see how it behaves? It should be pretty similar to the Elixir code you posted above
import cv2
cam1 = cv2.VideoCapture(0)
ok, frame = cam1.read()
# also I wasn't quite sure if the index 2 corresponds to the second camera on your setup
# or it might be a typo and thus the reason why V4L2 cannot read images from it
cam2 = cv2.VideoCapture(2)
ok, frame = cam2.read()
cam1.waitAny([cam1, cam2], 100)
Just discovered the
waitAny
function, which looks perfect for me, as I am dealing with multiple cameras and would like to have a timeout when attempting to read frames. However, I'm running into this error:Not sure if this is because I have something configured incorrectly, or if this is a bug. Any pointers?