Add current project. Compiles and runs on raspberry pi. Doesn't on ubuntu box (mismatch of opencv versions)

This commit is contained in:
Matt McWilliams 2023-12-28 22:19:10 -05:00
commit 835d509da5
4 changed files with 149 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build
bin
cmake-modules

17
CMakeLists.txt Normal file
View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.1)
PROJECT (opencv_fb)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules)
find_package(OpenCV HINTS /usr/local/opt/opencv /usr/local/Cellar/opencv REQUIRED)
set( NAME_SRC
opencv_fb.cpp
)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include )
link_directories( ${CMAKE_BINARY_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
add_executable( opencv_fb ${NAME_SRC} ${NAME_HEADERS} )
target_link_libraries( opencv_fb ${OpenCV_LIBS} )

9
compile.sh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
#mkdir -p bin
#g++ -o bin/opencv_fb -lopencv_core -lopencv_highgui -lopencv_imgproc opencv_fb.cpp
mkdir -p build
cd build
cmake ..
make -j

120
opencv_fb.cpp Normal file
View File

@ -0,0 +1,120 @@
/**
* @file opencv_fb.cpp
* Displays OpenCV video on framebuffer.
* Compile with
* g++ -o fbwrite_video -lopencv_core -lopencv_highgui -lopencv_imgproc fbwrite_video.cpp
*
* Contains code from https://stackoverflow.com/questions/4722301/writing-to-frame-buffer
*/
#include <iostream> // for cerr
#include <opencv2/imgproc/imgproc.hpp> // for cvtColor
#include <opencv2/highgui/highgui.hpp> // for VideoCapture
#include <fstream> // for ofstream
#include <boost/timer/timer.hpp> // for boost::timer::cpu_timer
using namespace std;
using namespace cv;
// this is C :/
#include <stdint.h> // for uint32_t
#include <sys/ioctl.h> // for ioctl
#include <linux/fb.h> // for fb_
#include <fcntl.h> // for O_RDWR
struct framebuffer_info {
uint32_t bits_per_pixel;
uint32_t xres_virtual;
uint32_t yres_virtual;
};
struct framebuffer_info get_framebuffer_info(const char* framebuffer_device_path) {
struct framebuffer_info info;
struct fb_var_screeninfo screen_info;
int fd = -1;
fd = open(framebuffer_device_path, O_RDWR);
if (fd >= 0) {
if (!ioctl(fd, FBIOGET_VSCREENINFO, &screen_info)) {
info.xres_virtual = screen_info.xres_virtual;
info.yres_virtual = screen_info.yres_virtual;
info.bits_per_pixel = screen_info.bits_per_pixel;
}
}
return info;
};
// C ends here
void display (Mat frame, framebuffer_info fb_info, ofstream& ofs) {
if (frame.depth() != CV_8U) {
cerr << "Not 8 bits per pixel and channel." << endl;
} else if (frame.channels() != 3) {
cerr << "Not 3 channels." << endl;
} else {
// 3 Channels (assumed BGR), 8 Bit per Pixel and Channel
int framebuffer_width = fb_info.xres_virtual;
int framebuffer_depth = fb_info.bits_per_pixel;
Size2f frame_size = frame.size();
Mat framebuffer_compat;
switch (framebuffer_depth) {
case 16:
cvtColor(frame, framebuffer_compat, COLOR_BGR2BGR565);
for (int y = 0; y < frame_size.height ; y++) {
ofs.seekp(y*framebuffer_width*2);
ofs.write(reinterpret_cast<char*>(framebuffer_compat.ptr(y)),frame_size.width*2);
}
break;
case 32: {
vector<Mat> split_bgr;
split(frame, split_bgr);
split_bgr.push_back(Mat(frame_size,CV_8UC1,Scalar(255)));
merge(split_bgr, framebuffer_compat);
for (int y = 0; y < frame_size.height ; y++) {
ofs.seekp(y*framebuffer_width*4);
ofs.write(reinterpret_cast<char*>(framebuffer_compat.ptr(y)),frame_size.width*4);
}
} break;
default:
cerr << "Unsupported depth of framebuffer." << endl;
}
}
}
Mat frameEffects (Mat frame) {
Mat grey;
Mat contrast;
Mat blur;
Mat flipper;
//flip(frame, flipper, 1);
//cvtColor(flipper, grey, COLOR_BGR2GRAY);
//grey.convertTo(contrast, -1, 1, 0);
//cvtColor(contrast, frame, COLOR_GRAY2BGR);
return frame;
}
int main(int, char**) {
const int frame_rate = 24;
int frameCount = 0;
framebuffer_info fb_info = get_framebuffer_info("/dev/fb0");
VideoCapture cap(0);
if(!cap.isOpened()) {
cerr << "Could not open video device." << endl;
return 1;
} else {
cout << "Successfully opened video device." << endl;
cap.set(CAP_PROP_FRAME_WIDTH, 1280);
cap.set(CAP_PROP_FRAME_HEIGHT, 720);
cap.set(CAP_PROP_FPS, frame_rate);
//cap.set(CAP_PROP_BUFFERSIZE,3);
cout << cap.get(CAP_PROP_FRAME_WIDTH) << "x" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl;
ofstream ofs("/dev/fb0");
Mat frame;
Mat displayFrame;
while (true) {
cap >> frame;
frame = frameEffects(frame);
resize(frame, displayFrame, Size(fb_info.xres_virtual, fb_info.yres_virtual), 2, 2, INTER_CUBIC);
display(displayFrame, fb_info, ofs);
waitKey(42);
}
}
}