Firefly开源社区

标题: 关于ffmedia ,请问图像转发的过程中,怎么添加自己的图像处理过程 [打印本页]

作者: chenwusong    时间: 2024-3-7 09:30
标题: 关于ffmedia ,请问图像转发的过程中,怎么添加自己的图像处理过程
我是用python开发,在itx-3588j上运行程序,要用这个ff_pymedia对输入的视频,进行处理后,再发送到输出口,目前看文档 ,所有的组件,都是派生于ModuleMedia,想问一下,这个组件,怎么添加一个自定义图像处理的功能阿?
我想对输入的视频画面,自动添加一些字幕或者logo后,再发送到输出端,查看了接口文档,setOutputDataCallback和addExternalConsumer都不太行,想请教一下,应该从哪里解决这个问题?


作者: nboxcn    时间: 2024-3-7 10:01
这种需求应该不复杂,参考demo里的rga范例,在rga层添加前景图文进行合成
作者: dengkx    时间: 2024-3-7 11:20
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有设置回调)再输出给他的消费者模块。在回调中使用传进来的buffer 获取数据getActiveData,该接口返回的是np数组,你可以使用cv操作该数组,更改里面的内容,他的消费者模块会接收到你更改后的buffer。
作者: chenwusong    时间: 2024-3-7 11:51
nboxcn 发表于 2024-3-7 10:01
这种需求应该不复杂,参考demo里的rga范例,在rga层添加前景图文进行合成

哇哇,多谢大佬指导,去看了demo_rgablend.cpp里代码,主要是设置了一个setBlendCallback,然后下面这是我改成python版本的回调代码,这个代码运行倒是不报错,但是做的添加字幕的功能,也没生效,大佬可以帮忙看看么?另外方便的话,请求可以加一下微信详细聊吗?309934668,这是我微信号,多谢多谢

def callback_blendv1(obj, MediaBuffer):
    vb = m.VideoBuffer.from_base(MediaBuffer)
    print('t1',vb)
    #data = vb.getActiveData()
    buf = vb.getData()
    try:
        img = buf.reshape((vb.getImagePara().vstride, vb.getImagePara().hstride, 3))
    except ValueError:
        exit(-1)
    buf_fd = vb.getBufFd()  # 为4
    cv2.putText(buf, 'test word', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv2.LINE_AA)
    vb.flushDrmBuf()
    rag = m.ModuleRga()
    rag.setPatBuffer(buf_fd,m.RGA_BLEND_MODE.BLEND_DST_OVER)

作者: chenwusong    时间: 2024-3-7 12:19
dengkx 发表于 2024-3-7 11:20
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有 ...

我之前就是找不到添加回调函数的地方,刚刚经过提醒,参考demo里的demo_rgablend.cpp,利用setBlendCallback添加回调,然后参考着c的代码,写了python版本的代码,但是目前回调函数确实被调用了,就是对图像做的改动,没有生效,可以帮忙看看问题原因么,如果可以的话,可以加下微信好友吗?309934668,这是我微信,多谢多谢
作者: chenwusong    时间: 2024-3-8 10:05
dengkx 发表于 2024-3-7 11:20
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有 ...

大佬在么?请问回调函数怎么添加阿?可以给个代码示例吗?cpp或者python的都行,这块实在搞不定阿
作者: dengkx    时间: 2024-3-8 11:15
本帖最后由 dengkx 于 2024-3-8 11:40 编辑
chenwusong 发表于 2024-3-8 10:05
大佬在么?请问回调函数怎么添加阿?可以给个代码示例吗?cpp或者python的都行,这块实在搞不定阿

将demo.py做以下更改:
diff --git a/demo/demo.py b/demo/demo.py
index 2219ba4..42a7b69 100644
--- a/demo/demo.py
+++ b/demo/demo.py
@@ -57,6 +57,9 @@ def cv2_extcall_back(obj, MediaBuffer):
         resolution = find_two_numbers(data.size//3, vb.getImagePara().hstride, vb.getImagePara().vstride)
         print("Try the recommended resolution: -o {}x{}".format(resolution[0], resolution[1]))
         exit(-1)
+
+    cv2.putText(img, 'test word', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv2.LINE_AA)
+    vb.flushDrmBuf()
     for i in range(obj.count):
         cv2.imshow(obj.name + str(i), img)
     cv2.waitKey(1)
@@ -221,9 +224,22 @@ def main():
                 print("Output image format is not 'BGR24', Use the '-b BGR24' option to specify image format.")
                 return 1
             cv_display = Cv2Display("Cv2Display", None, sync, args.cvdisplay)
-            cv_display.module = last_module.addExternalConsumer("Cv2Display", cv_display, cv2_extcall_back)
+            #cv_display.module = last_module.addExternalConsumer("Cv2Display", cv_display, cv2_extcall_back)
+            last_module.setOutputDataCallback(cv_display, cv2_extcall_back)

     if args.encodetype != -1:
+        input_para = last_module.getOutputImagePara()
+        if input_para.v4l2Fmt != m.v4l2GetFmtByName("NV12"):
+            output_para = input_para
+            output_para.v4l2Fmt = m.v4l2GetFmtByName("NV12")
+            encRga = m.ModuleRga(output_para,  m.RgaRotate(0))
+            encRga.setProductor(last_module)
+            ret = encRga.init()
+            if ret < 0:
+                print("rga init failed")
+                return 1
+            last_module = encRga
+
         enc = m.ModuleMppEnc(m.EncodeType(args.encodetype))
         enc.setProductor(last_module)
         enc.setBufferCount(8)


-----------------------------------------------------------------------
使用命令:./demo.py -i ../firefly.mp4 -b BGR24 -c 1 -s 1 -e 0 -m out.mp4
-i指向你要播放的文件或者流,cv显示并将保存文件。可以看到cv显示的画面有添加的内容,并且其他工具播放保存的out.mp4也可看到添加的内容。
demo主要更改:
1. cv回调中增加向视频帧添加文字,然后将添加的内容从cpu端刷新到dma端(flushDrmBuf)。
2. 将cv显示部分从添加外部消费者更改到rga回调里,这样cv处理后的数据就能同步输出到rga模块的消费者模块。
3. h264或h265编码需要YUV数据,添加rga模块将BGR24格式数据转成YUV数据给编码模块。
作者: chenwusong    时间: 2024-3-8 15:31
dengkx 发表于 2024-3-8 11:15
将demo.py做以下更改:
diff --git a/demo/demo.py b/demo/demo.py
index 2219ba4..42a7b69 100644

哇哇哇,多谢大佬提醒,看了大佬的代码,明白了一些原理,通过setOutputDataCallback可以设置图像的输出,不过需要把输出作为新的Producer,传给后面的显示器,才能生效。另外就是对图像的一些操作,不影响图像所在的内存地址,所以更改后的图像,才会往后传输。目前已经调通了代码,把更改后的图像,顺利显示在了显示器上。

另外有个新的问题,这是我更改图像的代码,如果我想对整个图像替换,目前的方法是,通过循环,重新给img进行赋值(即需要保证img的内存地址不变),实现图像的替换,请问有别的显式的方法,直接替换图像的方法吗?看了api,感觉setData、setActiveData这些函数像是显式的重新给图像赋值,但是直接传递图像np数组进去,又报错
    cv2.putText(img, 'test word', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv2.LINE_AA)
   
    # 内存地址不变的情况下,把图像内容替换为新的内容
    for i in range(img.shape[0]):
        img=default_img
        
    #print(img.shape,default_img.shape)
   
    vb.flushDrmBuf()




欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/) Powered by Discuz! X3.1