diff --git a/examples/framebuffer_OpenCV/.gitignore b/examples/framebuffer_OpenCV/.gitignore new file mode 100644 index 0000000..76b743d --- /dev/null +++ b/examples/framebuffer_OpenCV/.gitignore @@ -0,0 +1,6 @@ + +dist +build +.config.mk +.flash.conf.json + diff --git a/examples/framebuffer_OpenCV/README.md b/examples/framebuffer_OpenCV/README.md new file mode 100644 index 0000000..d6bf139 --- /dev/null +++ b/examples/framebuffer_OpenCV/README.md @@ -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 +S__80977923 + +### Acknowledgments +[nnn112358](https://github.com/nnn112358) + +### Reference link +- https://github.com/nnn112358/CoreMP135_framebuffer_OpenCV.git +- https://github.com/nihui/opencv-mobile.git \ No newline at end of file diff --git a/examples/framebuffer_OpenCV/SConstruct b/examples/framebuffer_OpenCV/SConstruct new file mode 100644 index 0000000..076d65c --- /dev/null +++ b/examples/framebuffer_OpenCV/SConstruct @@ -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()) diff --git a/examples/framebuffer_OpenCV/config_defaults.mk b/examples/framebuffer_OpenCV/config_defaults.mk new file mode 100644 index 0000000..754aad9 --- /dev/null +++ b/examples/framebuffer_OpenCV/config_defaults.mk @@ -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-" diff --git a/examples/framebuffer_OpenCV/img/06b.jpg b/examples/framebuffer_OpenCV/img/06b.jpg new file mode 100644 index 0000000..4d91c04 Binary files /dev/null and b/examples/framebuffer_OpenCV/img/06b.jpg differ diff --git a/examples/framebuffer_OpenCV/main/Kconfig b/examples/framebuffer_OpenCV/main/Kconfig new file mode 100644 index 0000000..e69de29 diff --git a/examples/framebuffer_OpenCV/main/SConstruct b/examples/framebuffer_OpenCV/main/SConstruct new file mode 100644 index 0000000..80ec5df --- /dev/null +++ b/examples/framebuffer_OpenCV/main/SConstruct @@ -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' + }) \ No newline at end of file diff --git a/examples/framebuffer_OpenCV/main/include/main.h b/examples/framebuffer_OpenCV/main/include/main.h new file mode 100644 index 0000000..45dcbb0 --- /dev/null +++ b/examples/framebuffer_OpenCV/main/include/main.h @@ -0,0 +1,3 @@ +#pragma once + + diff --git a/examples/framebuffer_OpenCV/main/src/main.cpp b/examples/framebuffer_OpenCV/main/src/main.cpp new file mode 100644 index 0000000..aab13ae --- /dev/null +++ b/examples/framebuffer_OpenCV/main/src/main.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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(vinfo.bits_per_pixel) << "\n" + << "Red: Offset " << static_cast(vinfo.red.offset) << ", Length " << static_cast(vinfo.red.length) << "\n" + << "Green: Offset " << static_cast(vinfo.green.offset) << ", Length " << static_cast(vinfo.green.length) << "\n" + << "Blue: Offset " << static_cast(vinfo.blue.offset) << ", Length " << static_cast(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"<(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(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; +} \ No newline at end of file