AI视觉处理--gstreamer应用


术语:
过滤器(filters)
转换器(convertors)
分流器(demuxers)
整流器(muxers)
编解码器(codecs)

检查支持类型:

$ gst-inspect-1.0

通过Opencv保存视频

// 组织gst管道字符串
QString gst_str = "appsrc \
                 ! videoconvert \
                 ! nvvidconv \
                 ! nvv4l2h264enc profile=4 bitrate=100000000 \
                 ! h264parse \ 
                 ! queue2 \
                 ! flvmux \
                 ! filesink location=/media/sda/data/test.mp4";    

vwriter = new VideoWriter(gst_str, 0, fps, (1280, 720));        
vwriter->write(img_mat);     // 保存视频流

profile - 设置视频质量 0 - 最低, 4 - 最高
bitrate - 设置视频比特率


rtmp推流:

char gst_str[]= "appsrc \
               ! videoconvert \
               ! nvvidconv \
               ! omxh264enc  bitrate=400000 \
               ! video/x-h264,stream-format=(string)byte-stream \
               ! h264parse  \
               ! flvmux \
               ! rtmpsink location=rtmp://127.0.0.1/hls/123";
vwriter = new VideoWriter(gst_str, 0, fps, Size(rtmpWidth, rtmpHeight));

从摄像机读入至应用程序:

nvarguscamerasrc \
! video/x-raw(memory:NVMM), width=(int)640, height=(int)480, format=(string)NV12, framerate=(fraction)60/1 \
! nvvidconv flip-method=0  \
! video/x-raw, width=(int)640, height=(int)480, format=(string)BGRx \
! videoconvert \
! video/x-raw, format=(string)BGR  \
! appsink

appsink - 输出至应用程序


从标准备摄像机设备推流视频:

$ gst-launch-1.0 v4l2src device="/dev/video0" \
  ! video/x-raw  \
  ! videoconvert \
  ! omxh264enc   \
  ! h264parse    \
  ! flvmux       \
  ! rtmpsink location="rtmp://192.168.10.106/hls/123"

本地文件推流至RTMP服务器

$ gst-launch-1.0 -v uridecodebin name=uridec uri=file:///media/sda/data/123.mp4 \
  ! videoconvert \
  ! omxh264enc   \
  ! h264parse   \
  ! flvmux       \
  ! rtmpsink location="rtmp://192.168.10.151/hls/123"

播放MP3:

$ gst-launch-1.0 filesrc location=/mnt/hgfs/code/gst/cd.mp3 ! decodebin ! audioconvert ! alsasink

播放MP4:

$ gst-launch-1.0 filesrc location=test.mp4 ! decodebin ! autovideosink

输入设备:
标准摄像机: v4l2src device="/dev/video0"
应用程序: appsrc

输出设备:

rtmp服务器:rtmpsink location="rtmp://192.168.10.151/hls/stream"
保存至文件:filesink location="/media/movie/test.mp4"
应用程序: appsink


https://blog.csdn.net/xiaonuo911teamo/article/details/110958685
https://cloud.tencent.com/developer/article/1676143


gst-launch-1.0 v4l2src ! xvimagesink

gst-launch-1.0 videotestsrc ! 'video/x-raw, width=(int)1280,height=(int)720,format(string)I420,framerate=(fraction)30/1' ! nveglglessink -e

filesrc - 从文件输入
appsrc - 应用程序输入

alsasink - alsa声卡输出
filesink - 文件输出
rtmpsink - RTMP输出

- 阅读全文 -

Python学习笔记--串口


安装串口模块:

$ pip3 install pyserial

打开串口:

import serial
 
serialPort="/dev/ttyACM0" 
baudRate=115200 
ser=serial.Serial(serialPort,baudRate,timeout=0.5) 

写数据:

result=ser.write("HelloWorld".encode("gbk"))
print("写总字节数:",result)

串口读取:

# 按行读取
gps_str = ser.readline()

关闭串口:

ser.close()

获取可用串口列表:

import serial.tools.list_ports
port_list = list(serial.tools.list_ports.comports())
print(port_list)

if len(port_list) == 0:
   print('无可用串口')
else:
    for i in range(0,len(port_list)):
        print(port_list[i])

https://www.cnblogs.com/dongxiaodong/p/9992083.html

- 阅读全文 -

OpenCV笔记--图片处理


图像添加文字:

// c++
cv::putText(img_mat,                // 图像(在原图上修改)
            "HelloWorld",           // 文字内容
            Point(50,50),           // 起始位置(文本左下角位置)
            FONT_HERSHEY_COMPLEX,   // 字体(仅支持Opencv内置的字体)
            1.2,                    // 缩放(字体大小)
            Scalar(0,0,0),          // 颜色GBR
            2);                     // 线宽

# Python
img_mat= cv2.putText(img_mat, "hello world!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 2)

- 阅读全文 -

Python学习笔记--共享内存


文章摘要: 本文主要介绍了Python对共享内存的操作方法,采用C语言将数据写入共享内存,通过Python读出,用于不同语言架构下的数据交换。

操作系统: Ubuntu20.04
硬件平台: Jetson Nx
软件版本: Python3


# !/usr/bin/python3
# -*- coding: utf-8 -*-
# 共享内存访问(通过动态链接库来调用)
from   ctypes import *
import ctypes
import ctypes.util
import numpy as np

SHM_SIZE = 1024*1024*100 
SHM_KEY = 0x123456  

# 导入librt动态链接库
try:  
    rt = CDLL('librt.so')  
except:  
    rt = CDLL('librt.so.1')  

# python中结构体定义(信号量数据结构)
class sembuf(Structure):
    _fields_ = [("sem_num", c_short), ("sem_op", c_short), ("sem_flg", c_short)]

#--------------------------------------------------------
# 共享内存函数导出
shmget          = rt.shmget  
shmget.argtypes = [c_int, c_size_t, c_int]  
shmget.restype  = c_int  
shmat           = rt.shmat  
shmat.argtypes  = [c_int, POINTER(c_void_p), c_int]  
shmat.restype   = c_void_p  

# 信号量函数导出
semget          = rt.semget  
semget.argtypes = [c_int, c_size_t, c_int]  
semget.restype  = c_int 

semop           = rt.semop  
semop.argtypes  = [c_int, POINTER(sembuf), c_size_t]  
semop.restype   = c_int 

#--------------------------------------------------------
# 信号量P操作
def sem_unlock(int_semid):
    postop         = sembuf()
    postop.sem_num = 0
    postop.sem_op  = 1
    postop.sem_flg = 4096
    semop(semid, postop, 1)

# 信号量V操作
def sem_lock(int_semid):
    postop         = sembuf()
    postop.sem_num = 0
    postop.sem_op  = -1
    postop.sem_flg = 4096
    semop(semid, postop, 1)
    
#--------------------------------------------------------
# 关联信号量与共享内存
shmid = shmget(SHM_KEY, SHM_SIZE, 0o666) 
semid = semget(SHM_KEY, 1, 0o666) 
print("shmid = %d"%shmid)
print("semid = %d"%semid)

if shmid < 0:  
    print ("system not infected")  
else:
    # 挂载共享内存  
    addr = shmat(shmid, None, 0)  
    #print(addr,type(addr))    
    
    # 从共享内存读数据
    sem_lock(semid) 
    read_buff = string_at(addr,2048)
    sem_unlock(semid)     
    
    # 转换成uint32_t数组后,可以通过下标访问
    image_array = np.frombuffer(read_buff, dtype=np.uint32, count=4, offset = 0)    
    flag   = int(image_array[0])
    width  = int(image_array[1])
    height = int(image_array[2])
    chnl   = int(image_array[3])   
    # 转换成字符串
    gps_info = read_buff[32:128].decode(encoding='utf-8')
    
    print(image_array)
    print(flag,width,height,chnl) 
    print(gps_info)

    # 写共享内存
    #sem_lock(semid)
    #libc.memset(ctypes.c_void_p(addr), ctypes.c_int(0x55), ctypes.c_int(10))
    #sem_unlock(semid)

图片格式转换:
图片格式:320x240 RGB888格式

# 转换成图片
share_end    = imgwidth*imgheight*imgnchannels + extlength
txt_read     = string_at(addr,share_end)
image_array  = np.frombuffer(txt_read, dtype=np.uint8, offset = extlength)
print(image_array.shape)

# 将一维数组转换成三维矩阵 
image_array = image_array.reshape(imgheight, imgwidth, imgnchannels)
print(image_array.shape)
# 保存图片
cv2.imwrite("image_array.jpg",image_array)

- 阅读全文 -

QT5开发笔记(26)-- 共享内存


文章摘要:
最近一个视觉算法的项目,需要通过C来抓取摄像机图像供推理程序调用,rtmp推流延迟过大,考虑采用共享内存模式实现.

#include "QSharedMemory"

QSharedMemory* shm = new QSharedMemory();
shm->setKey("HelloWorld");      /// 关联键值
///shm->create(2048,QSharedMemory::ReadWrite); /// 创建共享内存及信号量
shm->attach(QSharedMemory::ReadWrite);         /// 关联进程,关联后才能进行操作 

写操作:

QString s;
s = QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss.zzz");
qDebug() << s;
///shm->attach(QSharedMemory::ReadWrite);
uint64_t t1 = QDateTime::currentMSecsSinceEpoch();
shm->lock();
memset(shm->data(), 0, 100);
memcpy(shm->data(), s.toStdString().c_str(), s.length() + 1);
shm->unlock();
uint64_t t2 = QDateTime::currentMSecsSinceEpoch();
qDebug() << t2 - t1;

读操作:

uint64_t t1 = QDateTime::currentMSecsSinceEpoch();
shm->lock();
qDebug() << QString((char*)shm->data());
shm->unlock();
uint64_t t2 = QDateTime::currentMSecsSinceEpoch();
qDebug() << t2 - t1;

分离进程:

shm->detach();              /// 分离后不能再访问

查看共享内存及信号量

 $ ipcs -m -s

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态
0x5101fea6 19922976   nvidia     600        2048       0

--------- 信号量数组 -----------
键        semid      拥有者  权限     nsems
0x5101fea5 98306      nvidia     600        1

- 阅读全文 -


Copyright©2024 春天花会开, All Rights Reserved. Email: webmaster@oroct.com