Xavier红外相机(IP摄像头)开发记录

Xavier红外相机(IP摄像头)开发记录

1.相机基本信息

相机分辨率 640×512, 成像数据横向扫描,以16进制数据保存,每个像素按照16 bit存储,高两bit无效,为0,14 bit为有效数据。一帧图像文件大小为640×512×2 byte。使用摄像头需要网线连接相机端与主机端,并固定主机IP地址192.168.1.xxx,相机IP地址为192.168.1.201

在这里插入图片描述

2.数据采集程序

采集的图像数据存储在变量buffer中,为16进制数据,需要解码显示

修改Makefile中的平台编译器

# 修改编译平台
CC = aarch64-linux-gnu-gcc
CPP = aarch64-linux-gnu-g++
# 添加参数 -fPIC
linux-release:
	$(MAKE) all  -lpthread  CFLAGS="-Wall -DNDEBUG -O2" CPPFLAGS="-Wall -DNDEBUG -O2 -DBSD=1 -DSOCKLEN_T=socklen_t -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -fPIC"

编译命令

# 选择编译版本
make linux-release
# 链接
g++ CamManager.o Clinet_API.o main.o NetSocket.o TirNetInterface.o -o main 
# 运行
./main

输出
在这里插入图片描述
相机链接成功,接收100帧数据

以下为使用UltraEdit软件下查看一帧数据保存的内容,为16进制数据。

在这里插入图片描述

3.红外图像转码程序 16bit → \rightarrow 8bit

归一化阈值方案

8-bit像素值8pix
16-bit像素值16pix
normal_threshold为1200
8pix =(16pix / normal_threshold) × \times × 255.0
归一化阈值当出现异常高温区域时画面会出现黑洞,可能是像素值太大表示不出

线性映射方案 + CLAHE

首先遍历获取图像最大值max与最小值min
线性映射公式:
8pix = (16pix - min) × \times × 255.0/(max - min)
8pix:8-bit像素值;16pix:16-bit像素值
通过以上公式直接转换,对于不同场景,亮度-灰度变化太大
利用对比度受限自适应直方图均衡化算法增强,以减少亮度-灰度变化

#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>

int main(int argc, char** argv){
    ///参数
    short *data_buffer = new short[640*512]; //文件缓存
    std::string file_path = "/home/siu/"; //文件路径
    float normal_threshold = 1000.0; //显示的归一化阈值
    ///数据读取
    std::ifstream inF(file_path+"file.txt", std::ios::binary);
    inF.read((char *)data_buffer, sizeof(short) * (640*512));
    inF.close();
    while (1)
    {
        cv::Mat show_mat(512, 640, CV_8UC1, cv::Scalar::all(0));
        cv::Mat dst_mat(512, 640, CV_8UC1, cv::Scalar::all(0));
        
        // 寻找16bit图像最大、最小值
        float min = data_buffer[0], max=data_buffer[0];
        for (int r = 0; r < show_mat.rows; r++)
        {
             for (int c = 0; c < show_mat.cols; c++)
             {
                 float pix = data_buffer[(r * 640) + c]; 
                 if(pix > max)max = pix;
                 if(pix < min)min = pix;
             }
        }
        
        cout<< max <<"\n"<< min <<endl;
        
        //填充mat
        for (int x = 0; x < show_mat.rows; x++)
        {
            char *grayRow = show_mat.ptr<char>(x);
            for (int y = 0; y < show_mat.cols; y++)
            {
                float pix = data_buffer[(x * 640) + y];
                // grayRow[y] = ((pix / normal_threshold) * 255.0); // 归一化阈值显示方案
                grayRow[y] = ((pix - min)/(max - min))*255.0; // 线性映射
    
            }
        }

		// CLAHE 对比度受限自适应直方图均衡化
		cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
        clahe->setClipLimit(4);
        clahe->apply(show_mat, dst_mat);

        std::cout << "normal_threshold  : " << normal_threshold << std::endl;
        cv::imshow("image", dst_mat);
        cv::waitKey(0);
    }
    return 0;
}

编写CMakeLists.txt

# cmake needs this line
cmake_minimum_required(VERSION 3.20.2)
 
# Define project name
project(img-decode)

set(CMAKE_CXX_FLAGS "-std=c++11")
 
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)
 
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
 
# Add OpenCV headers location to your include paths
include_directories(${OpenCV_INCLUDE_DIRS})
 
# Declare the executable target built from your sources
add_executable(decode yours_ir.cpp)
 
# Link your application with OpenCV libraries
target_link_libraries(decode ${OpenCV_LIBS})

编译,进入代码文件夹执行以下编译命令

mkdir build && cd build
cmake ..
make
# 运行
./decode

转码图像显示效果

归一化阈值显示效果

在这里插入图片描述
线性映射显示效果

在这里插入图片描述

4.红外图像采集程序

将红外转码程序写入数据获取程序中,实时转码显示,利用opencv显示

Makefile需要添加opencv库,修改Makefile

INCLUDES = -I/usr/local/include/opencv
LIBS = -lpthread -fPIC
LIBS += -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml

编译完,链接时也需要链接opencv,否则出现undefined renference错误

g++ xx.o -o main $(pkg-config --cflags --libs opencv)

编译命令

make linux-release
g++ CamManager.o Clinet_API.o main.o NetSocket.o TirNetInterface.o -o main $(pkg-config --cflags --libs opencv4)
# 运行
./main

5.使用ROS发布采集的红外图像流

1.创建ROS工作空间

mkdir -p ~/test_ws/src
cd ~/test_ws/src
cd ..
catkin init
cd src

2.创建ROS功能包

catkin_create_pkg ir_cam sensor_msgs cv_bridge roscpp std_msgs image_transport
cd ..
catkin_make
source ./devel/setup.bash

将.h文件放入include/ir_cam/,将.cpp文件放入src/,修改.cpp中包含的头文件,如将#include "Clinet_API.h" 改为 #include "ir_cam/Clinet_API.h"

3.编写ROS发布程序

在main.cpp中编写ros发布程序,可参考博客编写

4.创建launch文件夹,编写launch文件,在文件中编写以下内容

<launch>
  <node name="ir_cam" pkg="ir_cam" type="ir_cam" output="screen" />
</launch>

5.编写CmakeList.txt文件

编写以下内容

find_package(catkin REQUIRED COMPONENTS
  cv_bridge
  image_transport
  roscpp
  sensor_msgs
  std_msgs
)
# opencv根据自己的路径修改
set(OpenCV_DIR /usr/include/opencv4)
find_package(OpenCV REQUIRED)
# 打印找到的opencv库信息
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
  ${OpenCV_INCLUDE_DIRS}
)
# 生成并链接第三方库,这一步会生成.so文件 libir_cam_lib.so
file(GLOB INC_DIR include/ir_cam/*.h) # 所有的.h文件
file(GLOB CPP_DIR src/*.cpp) # 所有的.cpp文件
add_library(${PROJECT_NAME}_LIB SHARED ${CPP_DIR} ${INC_DIR})
link_libraries(${PROJECT_NAME}_LIB)

# 生成可执行文件
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME}
	${PROJECT_NAME}_LIB
	${OpenCV_LIBS}
	${catkin_LIBRARIES}
)

6.编译运行

切换到test_ws路径下执行

catkin_make

编译成功

在这里插入图片描述

终端运行

roslaunch ir_cam ir_cam.launch

7.使用rviz查看发布的数据

rosrun rviz rviz

在这里插入图片描述
8.使用第三方库解码红外图像

静态链接库ImgProc.aImgProc.h头文件

ImgProc.h放入include文件夹,在include同级目录创建lib文件夹,将静态链接库名称修改为libImgProc.a放入其中。

main.cpp添加头文件#include "ir_cam/ImgProc.h",加入解码码代码处理获取的数据buffer,解码数据为imgDst

                    ImgPara imgSrc, imgDst;
                    // imgSrc.nWidth = m_imageW;
                    // imgSrc.nHeight = m_imageH;
                    imgSrc.nWidth = 640;
                    imgSrc.nHeight = 512;
                    imgSrc.wBpps = 14;
                    imgSrc.wChannel = 1;
                    //imgSrc.pData = (void*)m_rawData.c_str();
                    imgSrc.pData = (void *)buffer;
                    char pData[640*512];

                    // imgDst.nWidth = m_imageW;
                    // imgDst.nHeight = m_imageH;
                    imgDst.nWidth = 640;
                    imgDst.nHeight = 512;
                    imgDst.wBpps = 8;
                    imgDst.wChannel = 1;
                    imgDst.pData = (void *)pData;
                    Change14bitTO8bit(&imgSrc, &imgDst, FALSE, FALSE);

在CmakeList.txt中添加第三方静态库引用

find_library(LIB libImgProc.a)
# 若出现 NOT FOUND 添加绝对路径
# find_library(LIB libImgProc.a PATHS /path/绝对路径 ) 
link_directories(${LIB})
target_link_libraries(${PROJECT_NAME} ${LIB} libImgProc.a)

编译运行同上

6.订阅红外摄像头发布的图像话题用于视觉图像分析

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值