opencv安裝實錄附十幾行C++實現的一個人臉識別demo

良知猶存 發表於 2022-02-22
C++ OpenCV

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

前言:

之前寫過一篇在nano上使用opencv,nano上預設是安裝了opencv的庫,除了nano,我們自己電腦上也想使用opencv做一些平時影像處理驗證。

本來也是看一些資料安裝好的,覺得也沒必要寫。但是實際安裝還是出現了不少問題,所以記錄分享一下。

環境:
系統為ubuntu20.04
cv版本為 4.5
opencv安裝實錄附十幾行C++實現的一個人臉識別demo

作者:良知猶存

轉載授權以及圍觀:歡迎關注微信公眾號:羽林君

或者新增作者個人微信:become_me


oepncv介紹:

OpenCV的全稱是Open Source Computer Vision Library,是一個跨平臺的計算機視覺庫。OpenCV是由英特爾公司發起並參與開發,以BSD許可證授權發行,可以在商業和研究領域中免費使用。OpenCV可用於開發實時的影像處理、計算機視覺以及模式識別程式。

OpenCV用C++語言編寫(基本上現在新的開發和演算法都是用C++介面),它的主要介面也是C++語言,但是依然保留了大量的C語言介面。該庫也有大量的Python, Java and MATLAB/OCTAVE (版本2.5)的介面。這些語言的API介面函式可以透過線上文件獲取。現在也提供對於C#, Ch,Ruby的支援。

OpenCV可以在Windows, Android, Maemo, FreeBSD, OpenBSD, iOS, Linux和Mac OS等平臺上執行。使用者可以在Github獲得官方版本,或者從Git獲得開發版本。OpenCV也是用CMake.

安裝:

到了安裝環節了,先裝一堆依賴包。

sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev  pkg-config

下載opencv,下載地址:https://opencv.org/releases/,大可以點選Sources進行下載自己需要的版本。

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

剛開始選擇了4.1 安裝出錯之後,選擇了 4.5就一路按照4.1的經驗就裝好了,所以建議裝最新的。
opencv安裝實錄附十幾行C++實現的一個人臉識別demo

下載之後,我們就開始編譯安裝了,

常規操作:

cd opencv-4.5.5
mkdir build
cmake ../
make

但是事情不是按照命令這麼發展的,命令很少,解決問題確是很多。

cmake編譯的時候,推薦一個cmake圖形化工具,很方便。

sudo apt install cmake-qt-gui 

cmake-gui ../

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

我們Search一欄選擇我們要配置的cmake 選項,然後選擇 generate生成就好了。

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

cmake ../之後開始make:

make -j8

eigen庫未安裝
遇到fatal error: Eigen/Core: No such file or directory 這個錯誤:

方法1:

執行命令: sudo apt-get install libeigen3-dev 進行安裝。

方法2:
因為我安裝過一次了,所以我檢視了一下我的eigen,使用是locate 查詢了一下,locate eigen3

/usr/include/eigen3

/usr/include/eigen3/Eigen

發現了我的Eigen在eigen3目錄下。

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

所以我寫了一個軟鏈進行了連結

sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

繼續編譯 `make -j8

編譯 opencv 出現 internal compiler error:Segmentation fault,並且一直出現。

出錯的原因是(虛擬機器)執行記憶體不足,而大量template的擴充套件需要足夠的記憶體。
opencv安裝實錄附十幾行C++實現的一個人臉識別demo

下面給大家分享一種方法解決這個報錯,我選擇不管,繼續編譯。

可以通過臨時使用交換分割槽來解決:

sudo dd if=/dev/zero of=/swapfile bs=64M count=16

count的大小就是增加的swap空間的大小,64M是塊大小,所以空間大小是bs*count=1024MB

sudo mkswap /swapfile

把剛才空間格式化成swap格式

sudo swapon /swapfile

使用剛才建立的swap空間

在編譯完成後,最好可以關閉(釋放)交換空間

sudo swapoff /swapfile
sudo rm /swapfile

以上交換分割槽方法為引用了別的博主的片段

編譯的時候,也設定 cmake 選項 ENABLE_PRECOMPILED_HEADERS=OFF ,啟用預編譯頭支援。縮短構建時間。

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

sudo cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ENABLE_PRECOMPILED_HEADERS=OFF 

繼續 make -j8

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

終於編譯完成,進入了安裝階段 make install

sudo make install

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

可以看到安裝的動態庫和檔案都在/usr/local/目錄裡面
opencv安裝實錄附十幾行C++實現的一個人臉識別demo

配置全域性環境

OpenCV4預設不生成.pc檔案,所以我們需要自己去設定,也有人建議cmake後再加一條-D OPENCV_GENERATE_PKGCONFIG=ON才會生成。該編譯選項開啟生成opencv4.pc檔案,就支援pkg-config功能,這個部分大家可以自行去嘗試一下,我自己使用了手動新增的方法,比較笨,但是可以用。

cd /usr/local/lib
sudo mkdir pkgconfig && cd pkgconfig
sudo vi opencv.pc

檔案內容如下:對應的Version大家按照自己的版本修改,libs內容需要微調,後面有給我自己的情況。

prefix=/usr/local
exec_prefix=${prefix}
includedir=/usr/local/include
libdir=/usr/local/lib
 
Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.5.5
Libs: -L${exec_prefix}/lib -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_photo -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_hfs -lopencv_img_hash -lopencv_line_descriptor -lopencv_optflow -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_xfeatures2d -lopencv_shape -lopencv_video -lopencv_ml -lopencv_ximgproc -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_flann -lopencv_xobjdetect -lopencv_imgcodecs -lopencv_objdetect -lopencv_xphoto -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir}

後續在使用makefile -L連結時候 發現本機上面-lopencv_xfeatures2d 沒有此動態庫,所以就去掉了,大家也可以自行去測試,有些部分的版本有點區別,對應makefile的操作,大家可以移步看我之前的文章:jetson-nano opencv基礎使用

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

sudo vi /etc/bash.bashrc

修改bash.bashrc檔案,增加如下檔案

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH


再執行source /etc/bash.bashrc

這樣之後,我們就可以pkg-config查詢對應安裝好的opencv資訊了

pkg-config --modversion opencv

pkg-config --libs opencv 

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

此外我們也可以通過使用python3 import cv2的方法查詢opencv是否安裝成功

[email protected]:/usr/local/lib/pkgconfig$ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> print(cv2.__version__)
4.5.5
>>> 

對應的截圖:
opencv安裝實錄附十幾行C++實現的一個人臉識別demo

十幾行C++程式碼實現一個人臉識別

#include <stdio.h>
#include <iostream>
#include <vector>
#include<opencv2/opencv.hpp>
using namespace cv;


using namespace std;

void face_detection_demo() 
{
	std::string root_dir = "/home/lyn/Documents/opencv/learn_code/face_detector/";
	dnn::Net net = dnn::readNetFromTensorflow(root_dir+ "opencv_face_detector_uint8.pb", root_dir+"opencv_face_detector.pbtxt");
	VideoCapture capture(0);
	Mat frame;
	while (true) {
		capture.read(frame);
		if (frame.empty()) {
			break;
		}
		flip(frame, frame, 1);//左右翻轉 y對稱
		Mat blob = dnn::blobFromImage(frame, 1.0, Size(300, 300), Scalar(104, 177, 123), false, false);
		net.setInput(blob);// NCHW
		Mat probs = net.forward(); // 
		Mat detectionMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());
		// 解析結果
		for (int i = 0; i < detectionMat.rows; i++) {
			float confidence = detectionMat.at<float>(i, 2);
			if (confidence > 0.5) {
				int x1 = static_cast<int>(detectionMat.at<float>(i, 3)*frame.cols);
				int y1 = static_cast<int>(detectionMat.at<float>(i, 4)*frame.rows);
				int x2 = static_cast<int>(detectionMat.at<float>(i, 5)*frame.cols);
				int y2 = static_cast<int>(detectionMat.at<float>(i, 6)*frame.rows);
				Rect box(x1, y1, x2 - x1, y2 - y1);
				rectangle(frame, box, Scalar(0, 0, 255), 2, 8, 0);
			}
		}
		imshow("人臉檢測演示", frame);
		int c = waitKey(1);
		if (c == 27) { // 退出
			break;
		}
	}
}

int main(int argc,char **argv) {
  face_detection_demo();
  return 0;
}

CMakeLists.txt檔案

cmake_minimum_required( VERSION 2.8 )
project(opencv_test)
set(CMAKE_CXX_FLAGS  "-std=c++14 ${CMAKE_CXX_FLAGS} -Wall -Wformat -Wformat-security -Werror=format-security -Wunreachable-code")
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(opencv_test main.cpp )
target_link_libraries(opencv_test  ${OpenCV_LIBS})

對應的CMakeLists.txt檔案和jetson-nano opencv基礎使用基本一樣。詳細註解大家可以移步去看這篇文章。

上面那兩個檔案是呼叫opencv裡面dnn的例子,對應的檔案獲取方式如下:

涉及到pb檔案需要下載,有可能出現下載失敗的情況,如果大家需要這個檔案,也可以加我微信,我私發給需要的朋友們。

其中opencv_face_detector.pbtxt檔案在samples/dnn/face_detector/目錄中

cd opencv-4.5.5/samples/dnn/face_detector/
ls

opencv安裝實錄附十幾行C++實現的一個人臉識別demo


opencv_face_detector_uint8.pb比較麻煩些,需要下載。方式如下:

cd opencv-4.5.5/samples/dnn

python3 download_models.py

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

有Caffe模型,還有tensorflow模型。我們用的tensorflow模型,opencv_face_detector_uint8.pb檔案就是從這裡來。

Scalar(104, 177, 123)這個引數是/opencv-4.5.5/samples/dnn裡面對應的,models.yml檔案裡面有。

opencv安裝實錄附十幾行C++實現的一個人臉識別demo
如上所示,我也是直接使用了。

最終實現效果如下:

opencv安裝實錄附十幾行C++實現的一個人臉識別demo

結語

這就是我自己安裝opencv的過程分享。如果大家有更好的想法和需求,也歡迎大家加我好友交流分享哈。


作者:良知猶存,白天努力工作,晚上原創公號號主。公眾號內容除了技術還有些人生感悟,一個認真輸出內容的職場老司機,也是一個技術之外豐富生活的人,攝影、音樂 and 籃球。關注我,與我一起同行。

                              ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

推薦閱讀

【1】jetson nano開發使用的基礎詳細分享

【2】Linux開發coredump檔案分析實戰分享

【3】CPU中的程式是怎麼執行起來的 必讀

【4】cartographer環境建立以及建圖測試

【5】設計模式之簡單工廠模式、工廠模式、抽象工廠模式的對比

本公眾號全部原創乾貨已整理成一個目錄,回覆[ 資源 ]即可獲得。