jetson nano 在opencv拉流的视频上显示中文汉字(含c++完整源码)

问题

在jetson nano这样的嵌入式设备上,用opencv拉流,并在实时视频上面,显示汉字。

关于使用opencv/c++显示中文,网上文章分为两种:

  1. 使用freetype库+cv::putText()函数。该种方法仅适用于windows!
  2. 使用嵌入式Qt做中文显示。这是嵌入式设备做图形显示的正途,包括展现实时视频等,最好都用Qt做。

本人没有学过qt,因此找到一种取巧的办法,在win上生成中文图片,再将该图片蒙皮到视频帧,形成视频上有中文的效果。

解决方案

步骤一:生成中文图片

在windows上打开ppt,创建空白页面,选择“插入”–>“文本框”,选择“横排文本框”,创建一个文本框,里面填入你需要的中文。

将文本框的背景设置为白色,字体设置为红色(后面展示的字体就是红色的)。然后右键文本框,将该文本框保存为hanzi.png图片。

其中,需要注意的是,

  • 建议选择较为粗壮的字体,如“华文琥珀”等。
  • 框体不宜过大。

我的如图
在这里插入图片描述
文本框另存为hanzi.png。
请添加图片描述

步骤二:中文图片蒙皮到视频帧,形成中文显示效果

蒙皮简易代码参考博客:《opencv3/C++视频中叠加透明图片的实现》

  • 创建测试项目test_rtsp
mkdir ~/test_rtsp
cd test_rtsp

将上述文本框图片hanzi.png复制到该项目目录下。

  • c++源码

在项目目录test_rtsp下创建 CMakeLists.txt 和 test_rtsp.cpp,

touch CMakeLists.txt
touch test_rtsp.cpp

在CMakeLists.txt中添加如下内容:

cmake_minimum_required(VERSION 2.12)
project(DisplayRTSP)
set(CMAKE_CXX_STANDARD 14)
find_package(OpenCV REQUIRED)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")

add_executable(test_rtsp test_rtsp.cpp)
target_link_libraries(test_rtsp ${OpenCV_LIBS})

在test_rtsp.cpp中添加如下内容:

// video_test.cpp
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include <vector>
#include <stdlib.h>
#include "time.h"


static std::mutex mut;
static std::atomic_bool isOpen;
using namespace cv;
using namespace std;


static void frame_get(cv::Mat* pFrame, const std::string& adm, const std::string& pwd, const std::string& ip)
{
    cv::VideoCapture capture("rtsp://"+adm+":"+pwd+"@"+ip);

    if (!capture.isOpened()) {

        std::cout << "------reconnecting---------" << ip << std::endl;
        isOpen = false;

    }

    cv::Mat frame;
    while (isOpen) {

        capture >> frame;
        if (mut.try_lock()) {
            frame.copyTo(*pFrame);
            mut.unlock();
        }
        cv::waitKey(5);
    }
    capture.release();
}



int main(int argc, char* argv[])
{
    cv::setNumThreads(1);
    isOpen = true;

    
    cv::Mat frame, temp_frame;
    // 填入摄像头账号,我的为admin
    std::string adm = "admin";
    //填入摄像头密码,
    std::string pwd = "xxx";
    //填入摄像头ip
    std::string ip = "192.168.20.22";
    
    std::thread t(frame_get, &frame, adm, pwd, ip);

    //视频窗口设置
    cv::namedWindow(ip, cv::WINDOW_NORMAL);
    //cv::setWindowProperty(ip, cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN);
    cv::moveWindow(ip, 10, 10);
    cv::resizeWindow(ip, 1900, 1000);
    //给显示窗口分配一个线程,确保其正常运行
    cv::startWindowThread();


    //filename为hanzi.png的绝对路径
    std::string filename = "/home/aaeon/work/wangxin/test_rtsp1/hanzi.png";
    //cv::Mat png = cv::imread(filename);

    //以下过程为蒙皮的准备过程,filename为hanzi.png的绝对路径
    //imread(filename, 0),其中0为取图片的灰度图
    cv::Mat graypng = cv::imread(filename, 0);
    //cv::threshold中的150为区别hanzi.png中的红色字体和白色背景的阈值;红色的灰度值为255/2.0
    //此时graypng中,汉字为黑色,背景为白色
    cv::threshold(graypng, graypng, 150, 255, cv::THRESH_BINARY);
    //此时mask中,汉字为白色,背景为黑色
    cv::Mat mask = 255 - graypng;
    //png为hanzi.png原图
    cv::Mat png = cv::imread(filename);
    cv::Mat imROI;


    while (isOpen) {

        mut.lock();
        frame.copyTo(temp_frame);
        mut.unlock();
        if (temp_frame.empty()) {
            continue;
        }

        std::cout << "cols: " << temp_frame.cols << ", rows: " << temp_frame.rows << "\n";

        // 以下两行代码为蒙皮的处理过程
        imROI = temp_frame(cv::Rect(100, 100, png.cols, png.rows));
        //cv::imshow("imROI", imROI);
        png.copyTo(imROI, mask);

        cv::imshow(ip, temp_frame);
        cv::waitKey(100);
        if (cv::waitKey(1) == 'q') {
            break;
        }
    }
    cv::destroyAllWindows();
    isOpen = false;
    t.join();


    return 0;
}
aaeon@aaeon-desktop:~/work/wangxin/test_rtsp1$ vim test_rtsp.cpp
        if (mut.try_lock()) {
            frame.copyTo(*pFrame);
            mut.unlock();
        }
        cv::waitKey(5);
    }
    capture.release();
}



    

其中,我做注释的地方,都需要注意下,尤其是涉及摄像头账号、密码、ip等信息,需要你自己填写。

  • 编译及运行

在项目目录test_rtsp下,

cd ~/test_rtsp
mkdir build
cd build
cmake ..
make 
./test_rtsp

效果如下:
请添加图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值