Raspberry Pi CGI script with OpenCV not saving images - c++

I'm trying to create a CGI script that will take a picture and save it to the location I give it. I'm using the Raspberry Pi and the Pi camera module with the uv4l driver. I have also chosen to use Apache2.
Currently the script runs with no errors given and no errors in the Apache error log, but the image doesn't get saved. The camera does open because the red light appears on it. I also check to see if the image is empty which it isn't.
So far I have tried changing folder permissions so that the user pi owns everything. I have also tried to save over an already existing file but it never gets updated. I have never used Apache2 or CGI scripting before so I feel that the problem lies in there but I'm not entirely sure what to search because I am getting no errors. Any suggestions would be greatly appreciated.
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv){
cv::VideoCapture cap(-1);
if (!cap.isOpened()){
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>";
cout << "<h1> Camera didn't open </h1>";
cout << "</html>";
return -1;
}
//cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
//cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
int count = 40;
cv::Mat frame;
bool bSuccess = cap.read(frame);
while (count != 0){
count--;
}
if (!bSuccess){
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>";
cout << "<h1> Photo did't work get read in</h1>";
cout << "</html>";
return 0;
}
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>";
cout << "<h1> Photo Taken + Saved</h1>";
cout << "</html>";
cv::imwrite("/var/www/photos/Current.png", frame);
return 0;
}
I'm using this command to compile:
g++ -lopencv_core -lopencv_highgui -L/usr/lib/uv4l/uv4lext/armv6l -luv4lext -Wl,- rpath,'/usr/lib/uv4l/uv4lext/armv6l' time.cpp -o test_script.cgi

I fixed my own problem. The method imwrite() was saving over an already existing image without write permissions.

Related

OpenCV C++ VideoCapture on MacOS Monterey Not working

Hi I'm using M1 Macbook Pro 2021 with Monterey OS.
I've been trying to use my mac's internal webcam with OpenCV C++ VideoCapture class on Visual Studio Code, but i keep getting this weird errors. I've given both terminal and iTerm access to the Camera on my Mac's Preferences, but it still keeps giving me this error.
This is my Code,
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void camera_in()
{
VideoCapture cap;
cap.open(2, CAP_AVFOUNDATION);
if (!cap.isOpened())
{
cerr << "Camera open failed!" << endl;
return;
}
cout << "Frame width: " << cvRound(cap.get(CAP_PROP_FRAME_WIDTH)) << endl;
cout << "Frame height: " << cvRound(cap.get(CAP_PROP_FRAME_HEIGHT)) << endl;
Mat frame, inversed;
while (true)
{
cap >> frame;
if (frame.empty())
break;
inversed = ~frame;
imshow("frame", frame);
imshow("inversed", inversed);
if (waitKey(10) == 27)
break;
}
destroyAllWindows();
}
int main()
{
camera_in();
}
And this is the error i get from executing it.
2022-08-05 18:15:01.284398+0900 video[7664:45504] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x10b54c320> F8BB1C28-BAE8-11D6-9C31-00039315CD46
2022-08-05 18:15:01.291647+0900 video[7664:45504] HALC_ProxyObjectMap::_CopyObjectByObjectID: failed to create the local object
2022-08-05 18:15:01.291664+0900 video[7664:45504] HALC_ShellDevice::RebuildControlList: couldn't find the control object
2022-08-05 18:15:01.316885+0900 video[7664:45504] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x10c50bb40> 30010C1C-93BF-11D8-8B5B-000A95AF9C6A
I ran this code on my macbook pro m1 14" and it was working, I had to change:
cap.open(2, CAP_AVFOUNDATION);
to:
cap.open(0, CAP_AVFOUNDATION);
for it to work though (0 is the index of the built in webcam).

How to compile/run a cpp file in mac

I downloaded a webcam_face_pose_ex.cpp file from GitHub and now i want to compile and run it on my mac.
#include <dlib/opencv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
#include <X11/Xlib.h>
using namespace dlib;
using namespace std;
int main()
{
try
{
cv::VideoCapture cap(0);
if (!cap.isOpened())
{
cerr << "Unable to connect to camera" << endl;
return 1;
}
image_window win;
// Load face detection and pose estimation models.
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor pose_model;
deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;
// Grab and process frames until the main window is closed by the user.
while(!win.is_closed())
{
// Grab a frame
cv::Mat temp;
if (!cap.read(temp))
{
break;
}
// Turn OpenCV's Mat into something dlib can deal with. Note that this just
// wraps the Mat object, it doesn't copy anything. So cimg is only valid as
// long as temp is valid. Also don't do anything to temp that would cause it
// to reallocate the memory which stores the image as that will make cimg
// contain dangling pointers. This basically means you shouldn't modify temp
// while using cimg.
cv_image<bgr_pixel> cimg(temp);
// Detect faces
std::vector<rectangle> faces = detector(cimg);
// Find the pose of each face.
std::vector<full_object_detection> shapes;
for (unsigned long i = 0; i < faces.size(); ++i)
shapes.push_back(pose_model(cimg, faces[i]));
// Display it all on the screen
win.clear_overlay();
win.set_image(cimg);
win.add_overlay(render_face_detections(shapes));
}
}
catch(serialization_error& e)
{
cout << "You need dlib's default face landmarking model file to run this example." << endl;
cout << "You can get it from the following URL: " << endl;
cout << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
cout << endl << e.what() << endl;
}
catch(exception& e)
{
cout << e.what() << endl;
}
}
I tried g++ webcam_face_pose_ex.cpp command but I get:
webcam_face_pose_ex.cpp:30:10: fatal error: 'dlib/opencv.h' file not found
#include <dlib/opencv.h>
^~~~~~~~~~~~~~~
1 error generated.
Was Wondering what I could do to fix this?
The Example File Is Not Meant to be Compiled Using g++
Read the following to learn a bit about the -I flag and #include statements:
The webcam_face_pose_ex.cpp is part of a larger project and you won't be able to compile it on its own because it depends on other files. The #include directive specifies that in order to compile this program, code from the file specified by #includemust be compiled first. This means the entire dlib must be downloaded before compiling webcam_face_pose_ex.cpp. This project also requires opencv2 so we can download it and place the opencv2 folder in the dlib project folder.
Now we can open terminal and change directory into the dlib project folder and compile the file using the following command:
g++ -I. examples/webcam_face_pose_ex.cpp
Note we're specifying the directory of where to find the files specified by #include using the -I parameter as -I. this means to search the current working directory for the files. There it will find the dlib folder and dlib/opencv.h.
How ever, this isn't enough. When you execute the command, you'll encounter an error opencv2/opencv_modules.hpp: No such file or directory.
Solution
The dlib project documentation states that the examples should be built using cmake. Make sure to use cmake to compile the examples.

Launch OpenCV window from CLion

I want my application to create a window that will show my camera feed. my code is correct in regards to a vanilla implementation,
#include <opencv2/highgui.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
int main()
{
cv::VideoCapture cap(0);
const cv::String windowName = "helloThere";
cv::Mat frame;
while(1)
{
cap >> frame;
if(frame.empty()) // Check for invalid input
{
std::cout << "Could not open or find the frame" << std::endl;
return -1;
}
imshow(windowName, frame);
std::cout << frame << std::endl;
}
return 0;
}
but I think that, because I am launching from CLion, the window object isn't launching properly. I am able to log output from the frame, so my question is:
Does anyone know how to get a namedWindow to launch from a CLion runtime? sort of a newb question, but I think helpful for posterity. I haven't seen anything about this

"assertion failed (m.dims>=2) in Mat" Raspberry Pi OpenCV

I downloaded a project which allows to get frames from Pi camera module with OpenCV. When I try to run the downloaded code, It works without a problem. I just want to apply simple trheshold operation on frames but I got the error shown below.
I check the frames' type and channel. image.channels() returns 1 and image.type() returns 0. I can't see any reason for the threshold operation error.
What is the problem here?
The error:
The Code:
#include "cap.h"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main() {
namedWindow("Video");
// Create capture object, similar to VideoCapture
// PiCapture(width, height, color_flag);
// color_flag = true => color images are captured,
// color_flag = false => greyscale images are captured
PiCapture cap(320, 240, false);
Mat image,binary;
double time = 0;
unsigned int frames = 0;
cout << "Press 'q' to quit" << endl;
while(char(waitKey(1)) != 'q') {
double t0 = getTickCount();
image = cap.grab();
std::cout<<image.channels()<< endl;//check for channel
cout<<image.type()<< endl;//check for type
threshold(image,binary,150,255,THRESH_BINARY);//threshold operation
frames++;
if(!image.empty()) imshow("Hello", image);
else cout << "Frame dropped" << endl;
time += (getTickCount() - t0) / getTickFrequency();
cout << frames / time << " fps" << endl;
}
return 0;
}
Assertion m.ndims >= 2 is to check that the matrix in question is a valid two dimensional image. While you have a conditional to show the image only if it's not empty. But the assertion must be failing before the program reaches that conditional. So you shouldn't be seeing any image window pop up.

The call imshow() in OpenCV is not creating any output

I am trying to read data from an industrial camera using the V4l linux driver and C++. I would like to display the result using the OpenCV. I read the buffer, create an Mat object, which actually contains values in range 0...255.
The problem seems to be the imshow() call. When commenting this line out, an actual window without an image is displayed. Once uncommented no window is diplayed and also no output in terminal after this line is shown. I am not able to find a solution on my own, all examples I found look the same as my code to me.
Here is the code:
#include <fcntl.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <libv4l2.h>
#include <libv4l1.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#define BUFFERSIZE 357120 // 744 * 480
using namespace cv;
using namespace std;
int main(int argc, char **argv) {
int cameraHandle, i;
unsigned char pictureBuffer[BUFFERSIZE];
char cameraDevice[] = "/dev/video0";
struct v4l2_control V4L2_control;
/* open camera device */
if (( cameraHandle = v4l1_open(cameraDevice, O_RDONLY)) == -1 ){
printf("Unable to open the camera");
return -1;
}
// disable auto exposure
V4L2_control.id = V4L2_CID_EXPOSURE_AUTO;
V4L2_control.value = V4L2_EXPOSURE_SHUTTER_PRIORITY;
ioctl(cameraHandle, VIDIOC_S_CTRL, &V4L2_control);
// set exposure time
V4L2_control.id = V4L2_CID_EXPOSURE_ABSOLUTE;
V4L2_control.value = 2;
ioctl(cameraHandle, VIDIOC_S_CTRL, &V4L2_control);
// get 5 pictures to warm up the camera
for (i = 0; i <= 5; i++){
v4l1_read(cameraHandle, pictureBuffer, BUFFERSIZE);
}
// show pictures
Mat mat = Mat(744, 480, CV_8UC3, (void*)pictureBuffer);
cout << "M = " << endl << " " << mat << endl << endl; // display the image data
namedWindow("imagetest", CV_WINDOW_AUTOSIZE );
imshow("imagetest", mat);
waitKey(30);
cout << "test output" << endl;
//clenup
v4l1_close(cameraHandle);
destroyWindow("imagetest");
return 0;
}
EDIT:
Well, after running the code in terminal instead of ecipse I saw a segmentation fault Even commenting everything behind the
cout << "M = " << endl << " " << mat << endl << endl;
line gives me this error.
Solved. The problem lied in the wrong file format. CV_8UC1 or CV_8U instead of CV_8UC3 brought and an output. The difference between those formats is described here: In OpenCV, what's the difference between CV_8U and CV_8UC1?