jetson-nano opencv基础使用

简介: jetson-nano opencv基础使用

前言:

jetson nano前一篇给大家介绍了学习的一些思路和资料,今天继续给大家分享一篇在jetson nano使用opencv的文章。

OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。

在视觉处理中,opencv使用是基础的部分,所以在板卡使用过程中,opecv使用是第一道关。接下来我给大家介绍一下,在jetson nano里面使用opencv的python版本和c++版本的过程,其中c++使用部分会分别给大家介绍cmake和makefile编译两种方法。

作者:良知犹存

转载授权以及围观:欢迎关注微信公众号:羽林君

或者添加作者个人微信:become_me


oepcv介绍:

OpenCV 的目标是为计算机视觉需要解决的问题提供工具。在某些情况下,函数库中的高级功能可以有效解决计算机视觉中的问题。即使遇到不能够一次性解决的问题,函数库中的基础组件也具有足够的完备性来增强解决方案的性能,以应对任意的计算机视觉难题。

基本功能:

opencv的应用领域非常广泛,包括图像拼接、图像降噪、产品质检、人机交互、人脸识别、动作识别、动作跟踪、无人驾驶,此外,它还提供了机器学习模块,你可以使用正态贝叶斯、K最近邻、支持向量机、决策树、随机森林、人工神经网络等机器学习算法。

注:示例代码参考了其他博主文章。

opencv-python使用:

opencv-python使用比较简单,import导入cv2,这样我们就可以使用opencv-python模块的函数执行我们需要的动作了,下面介绍了一个比较简单的图像转换的demo。

opencv-python安装

pip3 install opencv-python

839886cd3c004deb9abdba851aa48a4c.png

示例代码

"""
彩图转灰度图
"""
#import 导入模块,每次使用模块中的函数都要是定是哪个模块。
#from…import * 导入模块,每次使用模块中的函数,直接使用函数就可以了;注因为已经知道该函数是那个模块中的了
from skimage.color import rgb2gray #skimage图形处理库 color是颜色空间转换子模块 pip install scikit-image
import numpy as np 
import matplotlib.pyplot as plt  #matlab的python库  pip install matplotlib
from PIL import Image # Python Imaging Library 图像处理库 pip install pillow
import cv2 
#图像灰度化
#cv2的方式
img = cv2.imread("/home/lyn/Pictures/318c944a7daa47eaa37eaaf8354fe52f.jpeg")
h,w = img.shape[:2] #获取图片的high和wide
img_gray=np.zeros([h,w],img.dtype) #创建一张和当前图片大小一样的单通道图片
for i in range(h):
    for j in range(w):
        m = img[i,j]
        img_gray[i,j] =int(m[0]*0.11+m[1]*0.59+m[2]*0.3) #将BGR坐标转换为gray坐标
print(img_gray)
print("image show grap:%s"%img_gray)
cv2.imshow("imageshow gray", img_gray)
#plt方式
plt.subplot(221) #表示将整个图像窗口分为2行2列, 当前位置为1.
img = plt.imread("/home/lyn/Pictures/318c944a7daa47eaa37eaaf8354fe52f.jpeg")
plt.imshow(img)
print("----image lenna -----")
print(img)
#灰度化
img_gray = rgb2gray(img)
plt.subplot(222)
plt.imshow(img_gray,cmap="gray")
print("-----image gray-------")
print(img_gray)
#二值化
img_binary = np.where(img_gray >= 0.5, 1, 0) 
print("-----imge_binary------")
print(img_binary)
print(img_binary.shape)
#plt方式
plt.subplot(223) 
plt.imshow(img_binary, cmap='gray')
plt.show()

839886cd3c004deb9abdba851aa48a4c.png

opencv c++使用:

opencv-c++安装

一般系统使用opencv 需要我们自己去官网:https://opencv.org,下载自己对应的包,然后camke->make->make install ,直至把编译好的opencv的文件安装到指定目录。

但是在Jetson Nano的镜像包中,预装了opencv4,版本的话是从4.1版本以后的。

我使用命令查询之后,我安装的镜像opencv版本是4.1.1

jetson@jetson-desktop:/usr/include/opencv4/opencv2$ opencv_version 
4.1.1

C++下开发Opencv需要进行一些额外的配置,先看一下opencv的头文件位置。

jetson中,opencv的头文件在这个目录 /usr/include/opencv4/,待会要把该目录写如编译链接文件中去。

839886cd3c004deb9abdba851aa48a4c.png

链接文件位置:

ls libopencv*

839886cd3c004deb9abdba851aa48a4c.png

具体路径为 /usr/lib/aarch64-linux-gnu,待会也要把该目录写如编译链接文件中去。

在c++开发中,我们一般会使用make工具或者cmake工具,帮助我们进行打包编译,这里我也给大家分享makefle和cmake两种c++调用opencv的库。

makefile

Makefile文件分享,注意这里 LIBS 链接的opencv链接的具体文件,需要一个一个写进去。这里我随便写了几个常用的包,大家可以按照需求自行添加。

OBJS = *.o 
CFLAGS = -Wall -g -std=c++11
CC = gcc
CPP = g++
INCLUDES +=-I  /usr/include/opencv4/ -I /usr/local/include #编译头文件目录
LIBS += -L/usr/lib/aarch64-linux-gnu -lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui -lopencv_objdetect #链接具体使用的库
target:${OBJS}
# g++  -o target boost_thread.o  -llua -ldl 
  @echo "-- start " ${CC} ${CFLAGS} ${OBJS}  -o $@  ${INCLUDES}  ${LIBS}
  $(CPP) ${CFLAGS} ${OBJS}  -o $@  ${INCLUDES}  ${LIBS}
clean:
  -rm -f *.o core *.core target
%.o:%.cpp #将src目录下所有的.cpp文件编译成.o文件
  ${CPP} ${CFLAGS} ${INCLUDES} -c  $<

代码show_img.cpp:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv)
{
  std::cout<<"hello opencv"<<std::endl;
  //灰度图显示
  Mat src = imread("/home/jetson/lyn_work/c++/sp_noise.png",IMREAD_GRAYSCALE);//读取进来的数据以矩阵的形势,第二个参数代表显示一张灰度图像。
  if (src.empty()) 
  {
    std::cout<<"could not load image"<<endl;//如果图片不存在 将无法读取,打印到终端。
  }
  //超过屏幕的图像无法显示时候调用此函数。
  namedWindow("输入窗口", WINDOW_GUI_EXPANDED);//创建了一个新窗口,参数1表示名称,第二个参数代表一个自由的比例
  imshow("输入窗口", src);//表示显示在新创建的输入窗口上,第一个参数表示窗口名称,src表示数据对象Mat 
  waitKey(0);//执行到这句,程序阻塞。参数表示延时时间。单位ms
  destroyAllWindows();//销毁前面创建的显示窗口
  return 0;
}

编译并执行:

make

839886cd3c004deb9abdba851aa48a4c.png

./target

839886cd3c004deb9abdba851aa48a4c.png

cmake

对应CMakeLists.txt文件内容:

cmake编译中,我们使用的链接对应OpenCV动态库文件就不用像Makefile文件那样要一个个添加了,cmake相当与添加了所有的opencv链接文件,这个是很方便的。所以后面cmake的类子里面,我多写了一个范例。

cmake_minimum_required( VERSION 2.8 )
# 声明一个 cmake 工程
project(opencv_learn)
# 设置编译模式
#set( CMAKE_BUILD_TYPE "Debug" )
#添加OPENCV库
#指定OpenCV版本,代码如下
#find_package(OpenCV 4.2 REQUIRED)
#如果不需要指定OpenCV版本,代码如下
find_package(OpenCV REQUIRED)
include_directories(
  ./src/)
#添加OpenCV头文件
include_directories(${OpenCV_INCLUDE_DIRS})
#显示OpenCV_INCLUDE_DIRS的值
message(${OpenCV_INCLUDE_DIRS})
FILE(GLOB_RECURSE TEST_SRC
  #src/*.cpp
  #src/*.c
  ${CMAKE_SOURCE_DIR}/*.cpp
  ${CMAKE_SOURCE_DIR}/*.cp
  )
# 添加一个可执行程序
# 语法:add_executable( 程序名 源代码文件 )
add_executable(target show_img.cpp ${TEST_SRC})
# 将库文件链接到可执行程序上
target_link_libraries(target  ${OpenCV_LIBS})

执行cmake编译:

mkdir build
cmake  ..
make

839886cd3c004deb9abdba851aa48a4c.png

demo1 :使用了和make示例同样的show_img.cpp代码文件,内容参考上面:

./target

839886cd3c004deb9abdba851aa48a4c.png

demo2 :使用C++编程读取CSI摄像头,可以看到已经可以正常的显示视频流图像了,但是由于vnc连接的原因,颜色也有些失真.

CMakeLists.txt增加两行:

add_executable(open_csi open_csi.cpp ${TEST_SRC})
target_link_libraries(open_csi  ${OpenCV_LIBS})

open_csi.cpp代码文件如下:

#include <iostream>
#include <string>
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/core.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/imgproc.hpp>
#include <opencv4/opencv2/objdetect.hpp>
#include <opencv4/opencv2/imgproc/types_c.h>
#include <opencv4/opencv2/videoio.hpp>
using namespace std;
using namespace cv;
string gstreamer_pipeline (int capture_width, int capture_height, int display_width, int display_height, int framerate, int flip_method)
{
    return "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=(int)" + to_string(capture_width) + ", height=(int)" +
           to_string(capture_height) + ", format=(string)NV12, framerate=(fraction)" + to_string(framerate) +
           "/1 ! nvvidconv flip-method=" + to_string(flip_method) + " ! video/x-raw, width=(int)" + to_string(display_width) + ", height=(int)" +
           to_string(display_height) + ", format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink";
}
int main( int argc, char** argv )
{
    int capture_width = 1280 ;
    int capture_height = 720 ;
    int display_width = 1280 ;
    int display_height = 720 ;
    int framerate = 60 ;
    int flip_method = 0 ;
    //创建管道
    string pipeline = gstreamer_pipeline(capture_width,
    capture_height,
    display_width,
    display_height,
    framerate,
    flip_method);
    std::cout << "使用gstreamer管道: \n\t" << pipeline << "\n";
    //管道与视频流绑定
    VideoCapture cap(pipeline, CAP_GSTREAMER);
    if(!cap.isOpened())
    {
        std::cout<<"打开摄像头失败."<<std::endl;
        return (-1);
    }
    //创建显示窗口
    namedWindow("CSI Camera", WINDOW_AUTOSIZE);
    Mat img;
    //逐帧显示
    while(true)
    {
        if (!cap.read(img))
        {
            std::cout<<"捕获失败"<<std::endl;
            break;
        }
        int new_width,new_height,width,height,channel;
            width=img.cols;
            height=img.rows;
            channel=img.channels();
        //调整图像大小
        new_width=640;
        if(width>800)
          {
             new_height=int(new_width*1.0/width*height);
           }
         resize(img, img, cv::Size(new_width, new_height));
        imshow("CSI Camera",img);
        int keycode = cv::waitKey(30) & 0xff ; //ESC键退出
            if (keycode == 27) break ;
    }
    cap.release();
    destroyAllWindows() ;
}

显示效果如截图所示:

839886cd3c004deb9abdba851aa48a4c.png

结语

这就是我对jetson nano使用opencv的基础分享,后面我们就可以基于opencv做一些更有意思的项目了,比如人脸识别,物体识别,姿态识别等等。如果大家有更好的想法和需求,也欢迎大家加我好友交流分享哈。


作者:良知犹存,白天努力工作,晚上原创公号号主。公众号内容除了技术还有些人生感悟,一个认真输出内容的职场老司机,也是一个技术之外丰富生活的人,摄影、音乐 and 篮球。关注我,与我一起同行。

目录
相关文章
|
11月前
|
存储 边缘计算 Ubuntu
使用 Jetson Orin Nano 在 Ubuntu 20.04 中编译安装 ROS2 Foxy
本文详细介绍了在 Jetson Orin Nano 类似的 ARM 设备上编译安装 ROS2 的 Foxy 分支的过程,包括从源代码编译、安装依赖库、设置环境变量等方面。同时,针对安装过程中可能遇到的问题,提供了相应的解决方案,以帮助读者顺利完成 ROS2 的安装。
473 0
|
编译器 Linux 开发工具
使用飞凌嵌入式IMX6UL-C1板子——qt+opencv环境搭建
使用飞凌嵌入式IMX6UL-C1板子——qt+opencv环境搭建
291 0
使用飞凌嵌入式IMX6UL-C1板子——qt+opencv环境搭建
|
存储 人工智能 计算机视觉
jetson Nano开箱使用方法
第一次接触jetson Nano如何使用,请看本文
341 0
|
消息中间件 Linux Kafka
【nvidia jetson xavier】 Linux系统安装+Deepstream 5.1环境部署
【nvidia jetson xavier】 Linux系统安装+Deepstream 5.1环境部署
266 0
|
JSON NoSQL Linux
VS2022OpenCV跨平台Linux CMake项目搭建过程(Jetson nano测试)
VS2022OpenCV跨平台Linux CMake项目搭建过程(Jetson nano测试)
672 0
VS2022OpenCV跨平台Linux CMake项目搭建过程(Jetson nano测试)
|
TensorFlow 算法框架/工具 Python
Jetson Nano 配置 Mediapipe(无编译)
Jetson Nano 配置 Mediapipe(无编译)
444 0
|
存储 人工智能 机器人
jetson nano开发使用的基础详细分享
jetson nano开发使用的基础详细分享
806 1
jetson nano开发使用的基础详细分享
嵌入式实践教程--opencv4 jetson编译mjpg-streamer
嵌入式实践教程--opencv4 jetson编译mjpg-streamer
|
Ubuntu
嵌入式实践教程--jetson nano安装ROS(国内源)
嵌入式实践教程--jetson nano安装ROS(国内源)
|
机器学习/深度学习 编解码 算法
Jetson Nano tensorrt部署YOLOX流程
Jetson Nano tensorrt部署YOLOX流程
669 0
Jetson Nano tensorrt部署YOLOX流程