我是用python开发,在itx-3588j上运行程序,要用这个ff_pymedia对输入的视频,进行处理后,再发送到输出口,目前看文档 ,所有的组件,都是派生于ModuleMedia,想问一下,这个组件,怎么添加一个自定义图像处理的功能阿?
我想对输入的视频画面,自动添加一些字幕或者logo后,再发送到输出端,查看了接口文档,setOutputDataCallback和addExternalConsumer都不太行,想请教一下,应该从哪里解决这个问题?
这种需求应该不复杂,参考demo里的rga范例,在rga层添加前景图文进行合成
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有设置回调)再输出给他的消费者模块。在回调中使用传进来的buffer 获取数据getActiveData,该接口返回的是np数组,你可以使用cv操作该数组,更改里面的内容,他的消费者模块会接收到你更改后的buffer。
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)
dengkx 发表于 2024-3-7 11:20
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有 …
我之前就是找不到添加回调函数的地方,刚刚经过提醒,参考demo里的demo_rgablend.cpp,利用setBlendCallback添加回调,然后参考着c的代码,写了python版本的代码,但是目前回调函数确实被调用了,就是对图像做的改动,没有生效,可以帮忙看看问题原因么{:4_96:},如果可以的话,可以加下微信好友吗?309934668,这是我微信,多谢多谢
dengkx 发表于 2024-3-7 11:20
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有 …
大佬在么?请问回调函数怎么添加阿?可以给个代码示例吗?cpp或者python的都行,这块实在搞不定阿
本帖最后由 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主要更改:
- cv回调中增加向视频帧添加文字,然后将添加的内容从cpu端刷新到dma端(flushDrmBuf)。
- 将cv显示部分从添加外部消费者更改到rga回调里,这样cv处理后的数据就能同步输出到rga模块的消费者模块。
- h264或h265编码需要YUV数据,添加rga模块将BGR24格式数据转成YUV数据给编码模块。
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数组进去,又报错{:4_105:}
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[i]=default_img[i]
#print(img.shape,default_img.shape)
vb.flushDrmBuf()