最近618優惠,買了樹莓派4,打算給娃當電腦用。到手之後先自己玩了下,做了一個簡單的掃碼程序。
樹莓派4相關硬件採購
- 樹莓派4的4GB版本。官方定價65美金,京東300減40到手389。
- Micro HDMI轉HDMI線。樹莓派4更換了電源接口。
- HDMI母對母轉接頭。用於延長HDMI線。
- 樹莓派智能貼身管家。包含可編程風扇,RGB燈和OLED顯示模塊。
系統安裝
- 官網下載官方系統https://www.raspberrypi.org/downloads/。
- 用Win32 Disk Imager把鏡像寫到sdcard裏。
- 卡插入樹莓派4,連接電源。注意:電源至少3A輸出,不要隨便連接USB接口供電。
系統配置
開啓I2C, VNC, 和SSH。
要通過Windows遠程連接,可以安裝tightvncserver和xrdp:
sudo apt update
sudo apt install tightvncserver xrdp
接下來檢查下磁盤空間是否足夠:
df -H
Filesystem Size Used Avail Use% Mounted on
/dev/root 32G 8.9G 21G 30% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 2.1G 0 2.1G 0% /dev/shm
tmpfs 2.1G 9.1M 2.1G 1% /run
tmpfs 5.3M 4.1k 5.3M 1% /run/lock
tmpfs 2.1G 0 2.1G 0% /sys/fs/cgroup
/dev/mmcblk0p1 265M 54M 211M 21% /boot
tmpfs 405M 4.1k 405M 1% /run/user/1000
如果sdcard存儲空間沒有被完全利用,可以通過raspi-config來配置:
sudo raspi-config
安裝OpenCV
OpenCV用來打開攝像頭獲取視頻幀。
下載最新版本源碼:https://github.com/opencv/opencv/releases
安裝所有依賴的包:
sudo apt install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libjpeg-dev libpng-dev libtiff-dev
編譯運行(這裏要花上幾個小時,很慢):
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DOPENCV_GENERATE_PKGCONFIG=ON ..
make -j4
sudo make install
C/C++代碼
下載Dynamsoft Barcode Reader SDK的樹莓派版本: https://www.dynamsoft.com/Downloads/Dynamic-Barcode-Reader-Download.aspx
創建CMakeLists.txt文件。裏面添加編譯鏈接需要的libDynamsoftBarcodeReader.so, OpenCV相關的庫,以及WiringPi:
link_directories("${PROJECT_SOURCE_DIR}/platforms/linux/")
find_package(OpenCV REQUIRED)
include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include/")
add_executable(BarcodeReader ssd1306_i2c.c BarcodeReader.cxx)
target_link_libraries (BarcodeReader "DynamsoftBarcodeReader" ${OpenCV_LIBS} wiringPi)
使用OpenCV獲取攝像頭視頻流:
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
Mat frame;
VideoCapture capture(0);
for (;;)
{
int key = waitKey(10);
if ((key & 0xff) == 27/*ESC*/) break;
capture >> frame; // read the next frame from camera
if (frame.empty())
{
cerr << "ERROR: Can't grab camera frame." << endl;
break;
}
imshow("Dynamsoft Barcode Reader", frame);
}
條形碼識別:
#include "DynamsoftBarcodeReader.h"
#include "BarcodeReaderConfig.h"
void textResultCallback(int frameId, TextResultArray *pResults, void * pUser)
{
char * pszTemp = NULL;
pszTemp = (char*)malloc(4096);
if (pResults->resultsCount == 0)
{
snprintf(pszTemp, 4096, "No barcode found.\r\n\r\n");
printf(pszTemp);
free(pszTemp);
CBarcodeReader::FreeTextResults(&pResults);
return;
}
for (int iIndex = 0; iIndex < pResults->resultsCount; iIndex++)
{
snprintf(pszTemp, 4096, "Barcode %d:\r\n", iIndex + 1);
printf(pszTemp);
snprintf(pszTemp, 4096, "Type: %s, Value: %s\r\n", pResults->results[iIndex]->barcodeFormatString, pResults->results[iIndex]->barcodeText);
printf(pszTemp);
draw_OLED(pszTemp);
}
free(pszTemp);
CBarcodeReader::FreeTextResults(&pResults);
}
CBarcodeReader reader;
int iRet = reader.InitLicense("LICENSE-KEY");
reader.SetTextResultCallback(textResultCallback,NULL);
capture >> frame;
int width = capture.get(CAP_PROP_FRAME_WIDTH);
int height = capture.get(CAP_PROP_FRAME_HEIGHT);
iRet = reader.StartFrameDecoding(10, 10, width, height, frame.step.p[0], IPF_RGB_888, "");
for (;;)
{
int key = waitKey(10);
if ((key & 0xff) == 27/*ESC*/) break;
capture >> frame; // read the next frame from camera
if (frame.empty())
{
cerr << "ERROR: Can't grab camera frame." << endl;
break;
}
reader.AppendFrame(frame.data);
imshow("Dynamsoft Barcode Reader", frame);
}
reader.StopFrameDecoding();
OLED顯示結果:
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include "ssd1306_i2c.h"
void draw_OLED(char* content)
{
ssd1306_clearDisplay();
ssd1306_drawString(content);
ssd1306_display();
}
最後編譯運行程序:
mkdir build
cd build
cmake ..
cmake –build .
./BarcodeReader
視頻演示
用樹莓派4,OLED,USB攝像頭搭建條形碼掃描設備
程序開機啓動
創建一個shell腳本 /home/pi/autostart.sh:
#!/bin/sh
/home/pi/raspberry-pi-cpp-barcode/build/BarcodeReader
修改執行權限:
chmod a+x autostart.sh
創建/home/pi/.config/autostart/autostart.desktop:
[Desktop Entry]
Type=Application
Exec=sh /home/pi/autostart.sh
重啓系統之後程序就會自動運行。