You've already forked M5Stack_Linux_Libs
mirror of
https://github.com/m5stack/M5Stack_Linux_Libs.git
synced 2026-05-20 11:01:38 -07:00
[add] framebuffer_OpenCV demo
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
|
||||
dist
|
||||
build
|
||||
.config.mk
|
||||
.flash.conf.json
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
# framebuffer_OpenCV
|
||||
This is a replica of the CoreMP135_framebuffer_OpenCV project by nnn112358, used to demonstrate the application of OpenCV on CoreMP135.
|
||||
|
||||
This project requires the use of a higher version of gcc.
|
||||
|
||||
```bash
|
||||
sudo apt install arm-linux-gnueabihf-g++ arm-linux-gnueabihf-gcc
|
||||
|
||||
scons
|
||||
|
||||
scons push
|
||||
```
|
||||
|
||||
### result in CoreMP135
|
||||
```bash
|
||||
root@M5Core135:~$ ./frame_buffer_opencv
|
||||
/dev/fb0 information
|
||||
--------------------------
|
||||
Frame Buffer Device Information:
|
||||
ID: stmdrmfb
|
||||
Memory Length: 1843200 bytes
|
||||
Type: 0
|
||||
Type Aux: 0
|
||||
Visual: 2
|
||||
Line Length: 2560 bytes per line
|
||||
--------------------------
|
||||
Variable Framebuffer Information:
|
||||
Resolution: 1280x720
|
||||
Virtual Resolution: 1280x720
|
||||
Bits Per Pixel: 16
|
||||
Red: Offset 11, Length 5
|
||||
Green: Offset 5, Length 6
|
||||
Blue: Offset 0, Length 5
|
||||
--------------------------
|
||||
/dev/fb1 information
|
||||
--------------------------
|
||||
Frame Buffer Device Information:
|
||||
ID: fb_ili9341
|
||||
Memory Length: 153600 bytes
|
||||
Type: 0
|
||||
Type Aux: 0
|
||||
Visual: 2
|
||||
Line Length: 640 bytes per line
|
||||
--------------------------
|
||||
Variable Framebuffer Information:
|
||||
Resolution: 320x240
|
||||
Virtual Resolution: 320x240
|
||||
Bits Per Pixel: 16
|
||||
Red: Offset 11, Length 5
|
||||
Green: Offset 5, Length 6
|
||||
Blue: Offset 0, Length 5
|
||||
--------------------------
|
||||
```
|
||||
### Apendix
|
||||
<img width="640" alt="S__80977923" src="https://github.com/nnn112358/CoreMP135_framebuffer_OpenCV/assets/27625496/78c63160-3e39-43e0-bf4f-8327f33d26bf">
|
||||
|
||||
### Acknowledgments
|
||||
[nnn112358](https://github.com/nnn112358)
|
||||
|
||||
### Reference link
|
||||
- https://github.com/nnn112358/CoreMP135_framebuffer_OpenCV.git
|
||||
- https://github.com/nihui/opencv-mobile.git
|
||||
@@ -0,0 +1,4 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
with open(str(Path(os.getcwd())/'..'/'..'/'tools'/'scons'/'project.py')) as f:
|
||||
exec(f.read())
|
||||
@@ -0,0 +1,6 @@
|
||||
# unix
|
||||
# CONFIG_TOOLCHAIN_PATH="/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin"
|
||||
# win
|
||||
# CONFIG_TOOLCHAIN_PATH="..\\gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf\\bin"
|
||||
|
||||
CONFIG_TOOLCHAIN_PREFIX="arm-linux-gnueabihf-"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 193 KiB |
@@ -0,0 +1,81 @@
|
||||
# project_root/src/SConscript
|
||||
import os
|
||||
import subprocess
|
||||
# Import the environment from the SConstruct file
|
||||
Import('env')
|
||||
with open(env['PROJECT_TOOL_S']) as f:
|
||||
exec(f.read())
|
||||
|
||||
|
||||
opencv_path = str(ADir('../../../github_source/opencv-mobile-2.4.13.7-armlinux'))
|
||||
|
||||
if not os.path.exists(opencv_path):
|
||||
zip_file = opencv_path + '.zip'
|
||||
zip_file_extrpath = opencv_path + '_tmp'
|
||||
down_url = "https://github.com/nihui/opencv-mobile/releases/download/v26/opencv-mobile-2.4.13.7-armlinux.zip"
|
||||
|
||||
if 'CONFIG_REPO_AUTOMATION' in os.environ:
|
||||
down = 'y'
|
||||
else:
|
||||
down = input('{} does not exist. Please choose whether to download it automatically? Y/N :'.format('opencv-mobile-2.4.13.7-armlinux'))
|
||||
down = down.lower()
|
||||
if down == 'y':
|
||||
# from git import Repo
|
||||
import requests
|
||||
import parse
|
||||
import zipfile
|
||||
import shutil
|
||||
try:
|
||||
# Downloading via HTTP (more common)
|
||||
if not os.path.exists(zip_file):
|
||||
response = requests.get(down_url)
|
||||
if response.status_code == 200:
|
||||
with open(zip_file, 'wb') as file:
|
||||
file.write(response.content)
|
||||
else:
|
||||
env.Fatal("{} down failed".format(down_url))
|
||||
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
|
||||
zip_ref.extractall(zip_file_extrpath)
|
||||
shutil.move(os.path.join(zip_file_extrpath, 'opencv-mobile-2.4.13.7-armlinux'), opencv_path)
|
||||
shutil.rmtree(zip_file_extrpath)
|
||||
print("The {} download successful.".format(down_url))
|
||||
except Exception as e:
|
||||
print('Please manually download {} to {} .'.format(down_url, zip_file))
|
||||
env.Fatal("Cloning failed.: {}".format(e))
|
||||
else:
|
||||
env.Fatal('Please manually download {} to {} .'.format(down_url, zip_file))
|
||||
|
||||
|
||||
libgomp = CC_cmd_execute(['-print-file-name=libgomp.so.1'])
|
||||
|
||||
SRCS = Glob('src/*.c*')
|
||||
INCLUDE = [ADir('include'), ADir('.')]
|
||||
PRIVATE_INCLUDE = []
|
||||
REQUIREMENTS = ['pthread', 'dl']
|
||||
STATIC_LIB = []
|
||||
DYNAMIC_LIB = [libgomp]
|
||||
DEFINITIONS = []
|
||||
DEFINITIONS_PRIVATE = []
|
||||
LDFLAGS = []
|
||||
LINK_SEARCH_PATH = []
|
||||
|
||||
INCLUDE += [ADir('../../../github_source/opencv-mobile-2.4.13.7-armlinux/arm-linux-gnueabihf/include')]
|
||||
STATIC_LIB += Glob('../../../github_source/opencv-mobile-2.4.13.7-armlinux/arm-linux-gnueabihf/lib/*.a')
|
||||
STATIC_LIB += Glob('../../../github_source/opencv-mobile-2.4.13.7-armlinux/arm-linux-gnueabihf/lib/*.a')
|
||||
|
||||
STATIC_FILES = [AFile('../img/06b.jpg')]
|
||||
|
||||
env['COMPONENTS'].append({'target':env['PROJECT_NAME'],
|
||||
'SRCS':SRCS,
|
||||
'INCLUDE':INCLUDE,
|
||||
'PRIVATE_INCLUDE':PRIVATE_INCLUDE,
|
||||
'REQUIREMENTS':REQUIREMENTS,
|
||||
'STATIC_LIB':STATIC_LIB,
|
||||
'STATIC_FILES':STATIC_FILES,
|
||||
'DYNAMIC_LIB':DYNAMIC_LIB,
|
||||
'DEFINITIONS':DEFINITIONS,
|
||||
'DEFINITIONS_PRIVATE':DEFINITIONS_PRIVATE,
|
||||
'LDFLAGS':LDFLAGS,
|
||||
'LINK_SEARCH_PATH':LINK_SEARCH_PATH,
|
||||
'REGISTER':'project'
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <stdexcept>
|
||||
#include <chrono>
|
||||
|
||||
|
||||
int view_information(struct fb_fix_screeninfo &finfo ,struct fb_var_screeninfo &vinfo){
|
||||
|
||||
|
||||
// デバイス情報の出力
|
||||
std::cout << "--------------------------\n"
|
||||
<< "Frame Buffer Device Information:\n"
|
||||
<< "ID: " << finfo.id << "\n"
|
||||
<< "Memory Length: " << finfo.smem_len << " bytes\n"
|
||||
<< "Type: " << finfo.type << "\n"
|
||||
<< "Type Aux: " << finfo.type_aux << "\n"
|
||||
<< "Visual: " << finfo.visual << "\n"
|
||||
<< "Line Length: " << finfo.line_length << " bytes per line\n"
|
||||
<< "--------------------------\n";
|
||||
|
||||
|
||||
|
||||
// スクリーン情報の出力
|
||||
std::cout << "Variable Framebuffer Information:\n"
|
||||
<< "Resolution: " << vinfo.xres << "x" << vinfo.yres << "\n"
|
||||
<< "Virtual Resolution: " << vinfo.xres_virtual << "x" << vinfo.yres_virtual << "\n"
|
||||
<< "Bits Per Pixel: " << static_cast<int>(vinfo.bits_per_pixel) << "\n"
|
||||
<< "Red: Offset " << static_cast<int>(vinfo.red.offset) << ", Length " << static_cast<int>(vinfo.red.length) << "\n"
|
||||
<< "Green: Offset " << static_cast<int>(vinfo.green.offset) << ", Length " << static_cast<int>(vinfo.green.length) << "\n"
|
||||
<< "Blue: Offset " << static_cast<int>(vinfo.blue.offset) << ", Length " << static_cast<int>(vinfo.blue.length) << "\n"
|
||||
<< "--------------------------\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
// フレームバッファデバイスのファイルディスクリプタ
|
||||
int fbfd0 = open("/dev/fb0", O_RDWR);
|
||||
if (fbfd0 == -1) {
|
||||
perror("Cannot open framebuffer device");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fbfd1 = open("/dev/fb1", O_RDWR);
|
||||
if (fbfd1 == -1) {
|
||||
perror("Cannot open framebuffer device");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 固定スクリーン情報の構造体
|
||||
struct fb_fix_screeninfo finfo0;
|
||||
if (ioctl(fbfd0, FBIOGET_FSCREENINFO, &finfo0)) {
|
||||
perror("Error reading fixed screen info");
|
||||
close(fbfd0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 固定スクリーン情報の構造体
|
||||
struct fb_fix_screeninfo finfo1;
|
||||
if (ioctl(fbfd1, FBIOGET_FSCREENINFO, &finfo1)) {
|
||||
perror("Error reading fixed screen info");
|
||||
close(fbfd1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 可変スクリーン情報の構造体
|
||||
struct fb_var_screeninfo vinfo0;
|
||||
if (ioctl(fbfd0, FBIOGET_VSCREENINFO, &vinfo0)) {
|
||||
perror("Error reading variable screen info");
|
||||
close(fbfd0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 可変スクリーン情報の構造体
|
||||
struct fb_var_screeninfo vinfo1;
|
||||
if (ioctl(fbfd1, FBIOGET_VSCREENINFO, &vinfo1)) {
|
||||
perror("Error reading variable screen info");
|
||||
close(fbfd1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout<<"/dev/fb0 information"<<std::endl;
|
||||
view_information(finfo0 ,vinfo0);
|
||||
std::cout<<"/dev/fb1 information"<<std::endl;
|
||||
view_information(finfo1 ,vinfo1);
|
||||
|
||||
|
||||
|
||||
// メモリマッピング
|
||||
char* fbAddr0 = static_cast<char*>(mmap(nullptr, finfo0.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd0, 0));
|
||||
if (fbAddr0 == MAP_FAILED) {
|
||||
perror("Failed to mmap");
|
||||
close(fbfd0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* fbAddr1 = static_cast<char*>(mmap(nullptr, finfo1.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd1, 0));
|
||||
if (fbAddr1 == MAP_FAILED) {
|
||||
perror("Failed to mmap");
|
||||
close(fbfd0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 画像の読み込み
|
||||
cv::Mat image = cv::imread("06b.jpg");
|
||||
if (image.empty()) {
|
||||
std::cerr << "Error: Image not found or empty.\n";
|
||||
munmap(fbAddr0, finfo0.smem_len);
|
||||
munmap(fbAddr1, finfo1.smem_len);
|
||||
|
||||
close(fbfd0);
|
||||
close(fbfd1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 画像のリサイズとカラーフォーマット変換
|
||||
cv::Mat displayport_image;
|
||||
cv::Mat lcd_image;
|
||||
|
||||
cv::resize(image, displayport_image, cv::Size(vinfo0.xres, vinfo0.yres));
|
||||
cv::resize(image, lcd_image, cv::Size(vinfo1.xres, vinfo1.yres));
|
||||
|
||||
// DisplayPort(HDMI):BGR888(24bit Color)⇒BGR565(16bit Color)
|
||||
cv::cvtColor(displayport_image, displayport_image, cv::COLOR_BGR2BGR565);
|
||||
|
||||
//LCD:BGR888(24bit Color)⇒BGR565(16bit Color)
|
||||
cv::cvtColor(lcd_image, lcd_image, cv::COLOR_BGR2BGR565);
|
||||
|
||||
// フレームバッファへの書き込み
|
||||
size_t screen_size0 = displayport_image.total() * displayport_image.elemSize();
|
||||
memcpy(fbAddr0, displayport_image.data, screen_size0);
|
||||
|
||||
size_t screen_size1 = lcd_image.total() * lcd_image.elemSize();
|
||||
memcpy(fbAddr1, lcd_image.data, screen_size1);
|
||||
|
||||
|
||||
// リソースの解放
|
||||
munmap(fbAddr0, finfo0.smem_len);
|
||||
munmap(fbAddr1, finfo1.smem_len);
|
||||
|
||||
close(fbfd0);
|
||||
close(fbfd1);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user