I am having an issue with saving images. I want to start with I do not want to resize the image after I receive it, I want the webcam to start with a native lower resolution which my camera supports. I am on Raspberry Pi OS. The supported resolutions supported.
pi@raspberrypi:~/Desktop $ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 176x144
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.033s (30.000 fps)
I tried to changed the resolution via terminal and via my c++ code with the following.
in C++
stream.set(cv::CAP_PROP_FRAME_WIDTH, 320);
stream.set(cv::CAP_PROP_FRAME_HEIGHT, 240);
in terminal I changed and checked the resolution
pi@raspberrypi:~/Desktop $ v4l2-ctl -d0 --set-fmt-video=width=320,height=240
pi@raspberrypi:~/Desktop $ v4l2-ctl -d0 --get-fmt-video | egrep 'Pixel Format|Width/Height'
Width/Height : 320/240
Pixel Format : 'YUYV' (YUYV 4:2:2)
pi@raspberrypi:~/Desktop $ v4l2-ctl -d2 --set-fmt-video=width=320,height=240
pi@raspberrypi:~/Desktop $ v4l2-ctl -d2 --get-fmt-video | egrep 'Pixel Format|Width/Height'
Width/Height : 320/240
Pixel Format : 'YUYV' (YUYV 4:2:2)
pi@raspberrypi:~/Desktop $ v4l2-ctl -d4 --set-fmt-video=width=320,height=240
pi@raspberrypi:~/Desktop $ v4l2-ctl -d4 --get-fmt-video | egrep 'Pixel Format|Width/Height'
Width/Height : 320/240
Pixel Format : 'YUYV' (YUYV 4:2:2)
When I go to run my code, it always saves at a higher resolution of 640x480. I am running 3 pthreads one for each thread. There isn't anything inherently wrong with the code, it saves but at the higher resolution. But when I run something like streamer -f jpeg -o image.jpeg It saves correctly
Simple example of c++ code which doesn't save at resolution of 320/240 but it does save at 640x480. Running the egrep code above also shows the width/height as revert back to 640/480. So I am sure OpenCV isn't playing nice when I change these values.
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <iostream>
#include <fstream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
int main(){
int i = 0;
cv::VideoCapture stream(0);
stream.set(cv::CAP_PROP_FRAME_WIDTH, 320);
stream.set(cv::CAP_PROP_FRAME_HEIGHT, 240);
cv::Mat3b Frame;
if(!stream.isOpened())
{
std::cout << "Cannot Open Camera: " + 0 + '\n';
}
else
{
std::cout << "Camera Open: " << 0 + '\n';
}
while (true)
{
stream.open(0);
const boost::posix_time::ptime now =
boost::posix_time::microsec_clock::local_time();
const boost::posix_time::time_duration td = now.time_of_day();
const long year = now.date().year();
const long month = now.date().month();
const long day = now.date().day();
const long hours = td.hours();
const long minutes = td.minutes();
const long seconds = td.seconds();
const long milliseconds = td.total_milliseconds() -
((hours * 3600 + minutes * 60 + seconds) * 1000);
char buf[80];
sprintf(buf, "%02ld%02ld%02ld_%02ld%02ld%02ld__%03ld",
year, month, day, hours, minutes, seconds, milliseconds);
std::string sBuf = buf;
std::string PATH = std::string("/home/pi/Desktop/") +
"camA" +
'/' +
"camA" +
'_' +
sBuf +
".jpeg";
stream.grab();
stream.retrieve(Frame);
cv::imwrite(PATH, Frame);
i++;
if (i == 1){
stream.release();
break;
}
}
}
Any Ideas what I can do to fix this? Maybe change the /dev/video* to read only, if that is allowed with OpenCV?