在mac電腦上管理這些gnu的庫一般都使用Homebrew,但總有一些你個性化的需要是官方的Homebrew配方無法滿足的。比如在屏幕的輸出中使用中文字符。
在OPENCV中輸出UTF8字符集早已經有人完成過類似的工作,方法是使用freetype的支持,程序中選擇使用的字庫,從而在屏幕上輸出任意的字符。但官方的Homebrew OPENCV的配方中,並不包含freetype的支持。這時候,只好自己來編譯OPENCV及contrib庫,因為freetype的支持就在contrib庫中。
編譯安裝
OPENCV的開發已經非常成熟,所以編譯過程並不復雜,大致包含如下的過程:
- 使用App Store安裝Xcode,隨后執行一次Xcode根據提示安裝其命令行工具。
- 使用brew安裝第三方的依賴庫,比如git/cmake/freetype等,很多依賴庫根據你使用的模塊不同,也有不同的需求。大多依賴庫如果你不安裝,OPENCV在編譯的時候會自動下載,但下載和編譯的過程都很慢,不如提前預裝編譯好的版本。
brew install cmake automake pkg-config ant autoconf git freetype
- 准備一個工作目錄,下載OPENCV和contrib的源碼(以OPENCV3.4為例):
mkdir source
cd source
git clone --single-branch -b 3.4 https://github.com/opencv/opencv.git
git clone --single-branch -b 3.4 https://github.com/opencv/opencv_contrib.git
master分支可能會包含一些並不穩定的代碼,所以不推薦使用master分支的代碼。
4. 配置、編譯及安裝
mkdir source/opencv/build
cd source/opencv/build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ ..
make -j4
sudo make install
上面這種方式通常能滿足大多的需求。如果你不想要在編譯中加入所有的擴展包,可以使用BUILD_opencv_*的參數屏蔽,比如:
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ -DBUILD_opencv_legacy=OFF ..
如果已經使用Homebrew安裝了OPENCV,並不想全部重新安裝,只想安裝freetype支持,可以手工將編譯出的freetype部分拷貝到系統路徑:
cp source/opencv-3.4.3/build/lib/libopencv_freetype* /usr/local/lib/
cp source/opencv_contrib-3.4/modules/freetype/include/opencv2/freetype.hpp /usr/local/include/opencv2/
然后還要在pkg-config配置文件中增加freetype庫的鏈接(使用make install的自動安裝是不需要這一步的):
vi /usr/local/lib/pkgconfig/opencv.pc
在Libs一行的最后增加:-lopencv_freetype
使用
使用freetype替代opencv原有的文字輸出功能很簡單,這里提供一個修改過的官方樣例,假設文件名為drawUtf8.cpp:
#include <opencv2/opencv.hpp>
#include <opencv2/freetype.hpp>
using namespace std;
using namespace cv;
int main(int argc,char **argv){
String text = "Hello世界!*毛*澤*東";
int fontHeight = 60;
int thickness = -1;
int linestyle = 8;
int baseline=0;
Ptr<freetype::FreeType2> ft2;
ft2 = freetype::createFreeType2();
//下面的字庫要自己下載並拷貝到需要的位置
ft2->loadFontData( "/user/local/ttf/maozedong.ttf", 0 );
namedWindow("box");
Mat img(600, 800, CV_8UC3, Scalar::all(0));
Size textSize = ft2->getTextSize(text,
fontHeight,
thickness,
&baseline);
if(thickness > 0){
baseline += thickness;
}
Point textOrg((img.cols - textSize.width) / 2,
(img.rows + textSize.height) / 2);
rectangle(img, textOrg + Point(0, baseline),
textOrg + Point(textSize.width, -textSize.height),
Scalar(0,255,0),1,8);
line(img, textOrg + Point(0, thickness),
textOrg + Point(textSize.width, thickness),
Scalar(0, 0, 255),1,8);
ft2->putText(img, text, textOrg, fontHeight,
Scalar::all(255), thickness, linestyle, true );
imshow("box",img);
while(1){ if(waitKey(100)==27)break; }
return 0;
}
隨后編譯執行:
#編譯
g++ -o drawUtf8 drawUtf8.cpp $(pkg-config --cflags --libs opencv)
#執行
./drawUtf8
執行的效果請參看題頭圖。
最后一種情況,如果編譯后只想在當前目錄使用,不想安裝。這種情況通常還是並不常見,因為默認OPENCV是使用動態編譯,各項依賴庫如果不安裝到系統路徑,是無法使用的。可以考慮在cmake參數中增加-DBUILD_SHARED_LIBS=0選項來進行靜態編譯,但這種情況我並沒有嘗試,參數僅來自於官方的介紹。
在當前目錄中進行應用程序的編譯最主要是配置頭文件路徑及鏈接庫文件的路徑,這些內容是比較多的,建議自己使用Makefile或者建立腳本文件來編譯,比如mk.sh:
#!/bin/sh
CFLAGS="-I source/opencv/include -I source/opencv_contrib/modules/freetype/include -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_photo -lopencv_fuzzy -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_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 -lopencv_freetype"
LDFLAGS="-L source/opencv/build/lib"
g++ $CFLAGS -o $1 $1.cpp $LDFLAGS
使用舉例:./mk.sh drawUtf8
。
參考資料
官方的編譯介紹:https://github.com/opencv/opencv_contrib
contrib模塊列表:https://github.com/opencv/opencv_contrib/tree/3.4/modules