系列文章目錄
提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動(dòng)添加
例如:第一章 Python 機(jī)器學(xué)習(xí)入門之pandas的使用
提示:寫完文章后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔
前言
提示:這里可以添加本文要記錄的大概內(nèi)容:
前面已經(jīng)完成了ESP32S3+LVGL+OV2640的工作,下一步就可以在這個(gè)基礎(chǔ)上去增加OPENCV的模塊了。
源代碼還是用的GitHub上的:
esp32-opencv
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、將OPENCV添加到工程
根據(jù)開源作者的描述,有三種方法。一個(gè)是直接用編譯好的庫(kù),直接使用。再一個(gè)是利用寫好的.sh文件重新編譯一下,生成庫(kù),然后使用。第三種就是所有的命令一步步來(lái)。咱們就不用多想了直接使用編譯好的庫(kù)。
Faster way:
The first way is to simply get the pre-built OpenCV library in esp32/lib/ folder, and copy it into your project (see Compiling-esp-idf-project-using-opencv)
Fast way:
The second way is by using the script in build_opencv_for_esp32.sh. This script automatically compiles OpenCV from this repository sources, and install the needed files into the desired project. It can be tweaked as needed to add and remove some parts (see esp32/doc/build_configurations.md).
The script has 2 arguments. The first is the path to the toolchain-esp32.cmake (default is $HOME/esp/esp-idf/tools/cmake/toolchain-esp32.cmake), and the second is the path where the OpenCV library is installed (default is in ./esp32/lib).
Detailed way:
The last way explains all the commands and modifications done to be able to compile and run OpenCV on the ESP32. The detailed procedure is in esp32/doc/detailed_build_procedure.md.
由于我對(duì)cmake文件這些還不了解,直接按照提供的方法,把生成的庫(kù)放到main文件夾下,修改CMakeList.txt。就可以直接編譯通過(guò)了。
二、解決 undefined reference to sysconf 錯(cuò)誤
編譯好之后,如果調(diào)用例程,就會(huì)出現(xiàn)這樣的提示。這個(gè)問(wèn)題好像是因?yàn)楂@取內(nèi)核數(shù)量的一個(gè)方法出現(xiàn)的異常,可能ESP32相關(guān)的支持還沒(méi)有完善起來(lái)。這里說(shuō)按照如下修改即可,但是查看下載后的源碼其實(shí)都已經(jīng)是修改好的,另外可能其他位置在編譯的時(shí)候也會(huì)報(bào)錯(cuò)。
parallel.cpp:949:58: undefined reference to sysconf
This error appeared while trying to use the canny() method of the imgproc module
Fix: Modify modules/core/src/parallel.cpp
Change the line 947 in
#if !defined(_WIN32) && !defined(__APPLE__) && !defined(ESP32)
unsigned ncpus = std::thread::hardware_concurrency(); /* If the value is not well defined or not computable, returns 0 */
所以簡(jiǎn)單一點(diǎn)直接將相關(guān)代碼刪除,然后返回0即可。
這樣修改完,通過(guò)上面的方法 build_opencv_for_esp32.sh可以再次編譯,然后生成新的庫(kù)文件。
三、生成新的Opencv庫(kù)文件
這里也做了一些改動(dòng),考慮到原來(lái)的庫(kù)是基于ESP32的,而且是IDF較早的版本。所以就考慮換成ESP32S3的,用最新的IDF版本,這樣跟工程更貼近一點(diǎn)。
過(guò)程比較簡(jiǎn)單:
1、復(fù)制Opencv目錄下的ESP32文件,改名字為ESP32S3;
2、 build_opencv_for_esp32.sh改名字 build_opencv_for_esp32s3.sh;
3、修改此文件的內(nèi)容:僅修改CMAKE_PATH即可,其他都不用,CMAKE里面的參數(shù)也不用了。
4、運(yùn)行這個(gè)bash文件,如果出現(xiàn)錯(cuò)誤會(huì)有提示,全部結(jié)束后在lib文件夾下就有新的庫(kù)文件了。
# path to the cmake file containing the toolchain informations
TOOLCHAIN_CMAKE_PATH=$HOME/esp/esp-idf/tools/cmake/toolchain-esp32s3.cmake
這個(gè)過(guò)程是在linux環(huán)境下進(jìn)行的,沒(méi)有搭建環(huán)境的,可以按照下面的StartGuide進(jìn)行。
docs.espressif.com
四、添加TTGO示例
需要注意的是opencv庫(kù)是C++環(huán)境下使用的,在之前工程里的c文件是不能直接使用的。當(dāng)然也可以重新將使用OPENCV的文件切換成c++的模式,不過(guò)C++早都忘差不多了,一時(shí)半會(huì)撿不起來(lái)。用老方法,做一個(gè)中間件,將其中的方法抽離出來(lái),通過(guò)接口調(diào)用。
main目錄下新建opencvMid文件夾,里面新增imgProcess.cpp和imgProcess.h文件。
imgProcess.cpp文件源文件如下:
#include "imgProcess.h"
#undef EPS // specreg.h defines EPS which interfere with opencv
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#define EPS 192
#define ESP32
#ifdef __cplusplus
extern "C"
{
#endif
#include "esp_system.h"
#include <esp_log.h>
#define TAG "OPENCV"
using namespace cv;
uint32_t imgProcess(int height, int width, void *pBuf, char ucMode)
{
Mat inputImage(height, width, CV_8UC2, pBuf); // rgb565 is 2 channels of 8-bit unsigned
static Mat imageCopy;
if(inputImage.empty()) {
ESP_LOGW(TAG, "Can't display empty image");
return 0;
}
if (ucMode == 0)
{
}
else if (ucMode == 1)
{
cvtColor(inputImage, inputImage, COLOR_BGR5652GRAY);
}
else if (ucMode == 2)
{
cvtColor(inputImage, inputImage, COLOR_BGR5652GRAY);
threshold(inputImage, inputImage, 128, 255, THRESH_BINARY);
}
else if (ucMode == 3)
{
cvtColor(inputImage, inputImage, COLOR_BGR5652GRAY);
// Reduce noise with a kernel 3x3
blur(inputImage, inputImage, Size(3, 3));
/** Apply the canny edges detector with:
* - low threshold = 50
* - high threshold = 4x low
* - sobel kernel size = 3x3
*/
int lowThresh = 40;
int kernSize = 3;
Canny(inputImage, inputImage, lowThresh, 4 * lowThresh, kernSize);
}
if(inputImage.type() == CV_8UC1) { // grayscale image
cvtColor(inputImage, imageCopy, COLOR_GRAY2BGR565, 1);
}
else if(inputImage.type() == CV_8UC3) { // BGR888 image
cvtColor(inputImage, imageCopy, COLOR_BGR2BGR565, 1);
}
else if(inputImage.type() == CV_8UC2) { // BGR565 image
inputImage.copyTo(imageCopy);
}
return (uint32_t)(imageCopy.ptr<uchar>(0));
}
#ifdef __cplusplus
}
#endif
這里主要是實(shí)現(xiàn)了一個(gè)接口,imgProcess,輸入?yún)?shù)為圖像的長(zhǎng)寬參數(shù),源圖像數(shù)據(jù)緩存,轉(zhuǎn)換的模式。返回的是轉(zhuǎn)換后的圖像緩存的地址。
ESP_LOGI(TAG, "Taking picture...");
pic = esp_camera_fb_get();
usCounter++;
my_img_dsc.data = (uint8_t *)imgProcess(240,320,(void *)(pic->buf),(usCounter++ / 100) % 4);
GucFlag = 1;
ESP_LOGI(TAG, "Picture taken! Its size was: %zu bytes", pic->len);
ESP_LOGI(TAG, "W: %d H:%d format:%d", pic->width,pic->height,pic->format);
esp_camera_fb_return(pic);
這樣在camera獲取圖像之后,通過(guò)imgProcess得到轉(zhuǎn)換后得圖像數(shù)據(jù)地址,賦值給lvgl圖片變量得數(shù)據(jù)地址參數(shù)。后面圖像刷新得時(shí)候,在屏幕上就顯示新的圖像了。
ESP32S3+LVGL+OV2640+OPENCV
總結(jié)
提示:這里對(duì)文章進(jìn)行總結(jié):
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-456425.html
感謝大家的支持。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-456425.html
到了這里,關(guān)于【EPS32S3學(xué)習(xí)筆記】ESP32+OPENCV+OV2640+LVGL的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!