OpenCV4 C++ 画图中文乱码问题 (Android JNI)
本文使用的编译环境是 Android NDK,其他的只需要使用自己的编译环境即可
Step1: 下载并编译 harfbuzz
git clone --single-branch -b 8.5.0 https://github.com/harfbuzz/harfbuzz.git
export ANDROID_SDK="/Users/wrj/Library/Android/sdk"
export PATH="${ANDROID_SDK}/cmake/3.22.1/bin:${PATH}"
export ANDROID_NDK="${ANDROID_SDK}/ndk/25.2.9519653"
export ANDROID_ABI="arm64-v8a"
export INSTALL_DIR="../install/harfbuzz"
if [ ! -d "build" ]; then
mkdir build
fi
pushd build
cmake -G "Unix Makefiles" \
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
-DCMAKE_MAKE_PROGRAM="${ANDROID_NDK}/prebuilt/darwin-x86_64/bin/make" \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_ABI=${ANDROID_ABI} \
-DANDROID_NDK=${ANDROID_NDK} \
-DANDROID_PLATFORM=android-24 \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
-DHB_BUILD_SUBSET=ON \
-DHB_HAVE_FREETYPE=OFF ..
cmake --build . -- -j6
make install
popd
Step2: 下载并编译 freetype2
git clone --single-branch -b VER-2-13-2 https://github.com/freetype/freetype.git
export ANDROID_SDK="/Users/wrj/Library/Android/sdk"
export PATH="${ANDROID_SDK}/cmake/3.22.1/bin:${PATH}"
export ANDROID_NDK="${ANDROID_SDK}/ndk/25.2.9519653"
export ANDROID_ABI="arm64-v8a"
export INSTALL_DIR="../install"
if [ ! -d "build" ]; then
mkdir build
fi
pushd build
cmake -G "Unix Makefiles" \
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
-DCMAKE_MAKE_PROGRAM="${ANDROID_NDK}/prebuilt/darwin-x86_64/bin/make" \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_ABI=${ANDROID_ABI} \
-DANDROID_NDK=${ANDROID_NDK} \
-DANDROID_PLATFORM=android-24 \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} ..
cmake --build . -- -j6
make install
popd
Step3: 下载 opencv_contrib
git clone --single-branch -b 4.10.0 https://github.com/opencv/opencv_contrib.git
Step4: 下载编译 opencv
git clone --single-branch -b 4.9.0 https://github.com/opencv/opencv.git
创建 options.txt 文件,用于编译 opencv 自带的库,文件内容如下:
-DBUILD_ZLIB=OFF
-DBUILD_TIFF=OFF
-DBUILD_OPENJPEG=OFF
-DBUILD_JASPER=OFF
-DBUILD_JPEG=OFF
-DBUILD_PNG=OFF
-DBUILD_OPENEXR=OFF
-DBUILD_WEBP=OFF
-DBUILD_TBB=OFF
-DBUILD_IPP_IW=OFF
-DBUILD_ITT=OFF
-DWITH_AVFOUNDATION=OFF
-DWITH_CAP_IOS=OFF
-DWITH_CAROTENE=OFF
-DWITH_CPUFEATURES=ON
-DWITH_EIGEN=OFF
-DWITH_FFMPEG=OFF
-DWITH_GSTREAMER=OFF
-DWITH_GTK=OFF
-DWITH_IPP=OFF
-DWITH_HALIDE=OFF
-DWITH_VULKAN=OFF
-DWITH_INF_ENGINE=OFF
-DWITH_NGRAPH=OFF
-DWITH_JASPER=OFF
-DWITH_OPENJPEG=OFF
-DWITH_JPEG=OFF
-DWITH_WEBP=OFF
-DWITH_OPENEXR=OFF
-DWITH_PNG=OFF
-DWITH_TIFF=OFF
-DWITH_OPENVX=OFF
-DWITH_GDCM=OFF
-DWITH_TBB=OFF
-DWITH_HPX=OFF
-DWITH_OPENMP=ON
-DWITH_PTHREADS_PF=OFF
-DWITH_V4L=OFF
-DWITH_CLP=OFF
-DWITH_OPENCL=OFF
-DWITH_OPENCL_SVM=OFF
-DWITH_VA=OFF
-DWITH_VA_INTEL=OFF
-DWITH_ITT=OFF
-DWITH_PROTOBUF=OFF
-DWITH_IMGCODEC_HDR=OFF
-DWITH_IMGCODEC_SUNRASTER=OFF
-DWITH_IMGCODEC_PXM=OFF
-DWITH_IMGCODEC_PFM=OFF
-DWITH_QUIRC=OFF
-DWITH_ANDROID_MEDIANDK=ON
-DWITH_TENGINE=OFF
-DWITH_ONNX=OFF
-DWITH_TIMVX=OFF
-DWITH_OBSENSOR=OFF
-DWITH_CANN=OFF
-DWITH_FLATBUFFERS=OFF
-DBUILD_SHARED_LIBS=OFF
-DBUILD_opencv_apps=OFF
-DBUILD_ANDROID_PROJECTS=OFF
-DBUILD_ANDROID_EXAMPLES=OFF
-DBUILD_DOCS=OFF
-DBUILD_EXAMPLES=OFF
-DBUILD_PACKAGE=OFF
-DBUILD_PERF_TESTS=OFF
-DBUILD_TESTS=OFF
-DBUILD_WITH_STATIC_CRT=OFF
-DBUILD_FAT_JAVA_LIB=OFF
-DBUILD_ANDROID_SERVICE=OFF
-DBUILD_JAVA=OFF
-DBUILD_OBJC=OFF
-DBUILD_KOTLIN_EXTENSIONS=OFF
-DENABLE_PRECOMPILED_HEADERS=OFF
-DENABLE_FAST_MATH=ON
-DCV_TRACE=OFF
-DBUILD_opencv_java=OFF
-DBUILD_opencv_gapi=OFF
-DBUILD_opencv_objc=OFF
-DBUILD_opencv_js=OFF
-DBUILD_opencv_ts=OFF
-DBUILD_opencv_python2=OFF
-DBUILD_opencv_python3=OFF
-DBUILD_opencv_dnn=OFF
-DBUILD_opencv_imgcodecs=ON
-DBUILD_opencv_videoio=ON
-DBUILD_opencv_calib3d=OFF
-DBUILD_opencv_flann=OFF
-DBUILD_opencv_objdetect=OFF
-DBUILD_opencv_stitching=OFF
-DBUILD_opencv_ml=OFF
创建 extra_options.txt 文件,用于编译 opencv_contrib 库,文件内容如下:
-DWITH_FREETYPE=ON
-DBUILD_opencv_alphamat=OFF
-DBUILD_opencv_aruco=OFF
-DBUILD_opencv_bgsegm=OFF
-DBUILD_opencv_bioinspired=OFF
-DBUILD_opencv_cannops=OFF
-DBUILD_opencv_ccalib=OFF
-DBUILD_opencv_cnn_3dobj=OFF
-DBUILD_opencv_cudaarithm=OFF
-DBUILD_opencv_cudabgsegm=OFF
-DBUILD_opencv_cudacodec=OFF
-DBUILD_opencv_cudafeatures2d=OFF
-DBUILD_opencv_cudafilters=OFF
-DBUILD_opencv_cudaimgproc=OFF
-DBUILD_opencv_cudalegacy=OFF
-DBUILD_opencv_cudaobjdetect=OFF
-DBUILD_opencv_cudaoptflow=OFF
-DBUILD_opencv_cudastereo=OFF
-DBUILD_opencv_cudawarping=OFF
-DBUILD_opencv_cudev=OFF
-DBUILD_opencv_cvv=OFF
-DBUILD_opencv_datasets=OFF
-DBUILD_opencv_dnn_objdetect=OFF
-DBUILD_opencv_dnn_superres=OFF
-DBUILD_opencv_dnns_easily_fooled=OFF
-DBUILD_opencv_dpm=OFF
-DBUILD_opencv_face=OFF
-DBUILD_opencv_freetype=ON
-DBUILD_opencv_fuzzy=OFF
-DBUILD_opencv_hdf=OFF
-DBUILD_opencv_hfs=OFF
-DBUILD_opencv_img_hash=OFF
-DBUILD_opencv_intensity_transform=OFF
-DBUILD_opencv_julia=OFF
-DBUILD_opencv_line_descriptor=OFF
-DBUILD_opencv_matlab=OFF
-DBUILD_opencv_mcc=OFF
-DBUILD_opencv_optflow=OFF
-DBUILD_opencv_ovis=OFF
-DBUILD_opencv_phase_unwrapping=OFF
-DBUILD_opencv_plot=OFF
-DBUILD_opencv_quality=OFF
-DBUILD_opencv_rapid=OFF
-DBUILD_opencv_reg=OFF
-DBUILD_opencv_rgbd=OFF
-DBUILD_opencv_saliency=OFF
-DBUILD_opencv_sfm=OFF
-DBUILD_opencv_shape=OFF
-DBUILD_opencv_signal=OFF
-DBUILD_opencv_stereo=OFF
-DBUILD_opencv_structured_light=OFF
-DBUILD_opencv_superres=OFF
-DBUILD_opencv_surface_matching=OFF
-DBUILD_opencv_text=OFF
-DBUILD_opencv_tracking=OFF
-DBUILD_opencv_videostab=OFF
-DBUILD_opencv_viz=OFF
-DBUILD_opencv_wechat_qrcode=OFF
-DBUILD_opencv_xfeatures2d=OFF
-DBUILD_opencv_ximgproc=OFF
-DBUILD_opencv_xobjdetect=OFF
-DBUILD_opencv_xphoto=OFF
编译 opencv 使得其画图支持中文:
export ANDROID_SDK="/Users/wrj/Library/Android/sdk"
export PATH="${ANDROID_SDK}/cmake/3.22.1/bin:${PATH}"
export ANDROID_NDK="${ANDROID_SDK}/ndk/25.2.9519653"
export ANDROID_ABI="arm64-v8a"
export INSTALL_DIR="../install"
if [ ! -d "build" ]; then
mkdir build;
fi
cd build
cmake -G "Unix Makefiles" \
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
-DCMAKE_MAKE_PROGRAM="${ANDROID_NDK}/prebuilt/darwin-x86_64/bin/make" \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_ABI=${ANDROID_ABI} \
-DANDROID_NDK=${ANDROID_NDK} \
-DANDROID_PLATFORM=android-24 \
`cat ../options.txt` \
-DOPENCV_EXTRA_MODULES_PATH="/Users/wrj/AndroidStudioProjects/opencv_contrib/modules" \
`cat ../extra_options.txt` \
-DFREETYPE_FOUND=1 \
-DFREETYPE_INCLUDE_DIRS="/Users/wrj/AndroidStudioProjects/freetype-2.10.0/install/include/freetype2" \
-DFREETYPE_LIBRARY="/Users/wrj/AndroidStudioProjects/freetype-2.10.0/install/lib" \
-DHARFBUZZ_FOUND=1 \
-DHARFBUZZ_INCLUDE_DIRS="/Users/wrj/AndroidStudioProjects/harfbuzz/install/include/harfbuzz" \
-DHARFBUZZ_LIBRARIES="/Users/wrj/AndroidStudioProjects/harfbuzz/install/lib" \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} ..
cmake --build . -- -j6
make install
cd ..
编译第三方ade 库:
export ADE_INSTALL_DIR=${INSTALL_DIR}/sdk/native/3rdparty/libs/arm64-v8a
cd 3rdparty
if [ ! -d "ade" ]; then
git clone https://github.com/opencv/ade.git
fi
cd ade
if [ ! -d "build" ]; then
mkdir build;
fi
cd build
cmake -G "Unix Makefiles" \
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
-DCMAKE_MAKE_PROGRAM="${ANDROID_NDK}/prebuilt/darwin-x86_64/bin/make" \
-DANDROID_ABI=${ANDROID_ABI} \
-DANDROID_NDK=${ANDROID_NDK} \
-DANDROID_PLATFORM=android-24 \
-DCMAKE_INSTALL_PREFIX="install" ..
make install
mv install/lib/libade.a ../../../install/sdk/native/3rdparty/libs/arm64-v8a
编译结果如下:

Step5: 验证是否解决中文乱码问题
网上下载中文字符集或者使用系统自带字符集,找到字符集所在路径,本文使用的路径是 /Users/wrj/projects/test/FangZhengKaiTiJianTi-1.ttf
#include <iostream>
#include <opencv2/freetype.hpp>
#include <opencv2/opencv.hpp>
#include <string>
#include <vector>
bool drawResults(cv::Mat &rgb, const std::string &results, int max_time = -1) {
std::vector<std::string> parsed_str;
std::string tmp;
tmp.reserve(5);
for (char ch : results) {
if (ch == '$') {
parsed_str.push_back(std::move(tmp));
tmp.clear();
} else {
tmp.push_back(ch);
}
}
if (!tmp.empty()) {
parsed_str.push_back(std::move(tmp));
}
std::string time_str;
if (max_time > 0) {
time_str = "倒计时: " + std::to_string(max_time - std::stoll(parsed_str[1])) + " 秒";
} else {
time_str = "用时: " + parsed_str[1] + " 秒";
}
int fontHeight = 25;
int thickness = -1;
int baseline = 0;
int lineType = cv::LINE_AA;
cv::Scalar color(255, 255, 0);
if (thickness > 0) {
baseline += thickness;
}
std::string text1 = "成功/总数: " + parsed_str[3] + '/' + parsed_str[4] + " " + time_str;
auto ft2 = cv::freetype::createFreeType2();
ft2->loadFontData("/Users/wrj/projects/test/FangZhengKaiTiJianTi-1.ttf", 0);
cv::Size text_size1 = ft2->getTextSize(text1, fontHeight, thickness, &baseline);
int x = 10, y = 10 + text_size1.height;
ft2->putText(rgb, text1, cv::Point(x, y), fontHeight, color, thickness, lineType, true);
return true;
}
int main() {
cv::VideoCapture cap("/Users/wrj/projects/test/720.mp4");
cv::Mat bgr, rgb;
initId2Str();
while (cap.read(bgr)) {
cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
drawResults(rgb, "YW$90$0$5$10$141$142$143", 120);
cv::cvtColor(rgb, bgr, cv::COLOR_RGB2BGR);
cv::imshow("", bgr);
cv::waitKey(0);
}
cap.release();
return 0;
}
结果如下:


浙公网安备 33010602011771号