图像编码-h264和jpeg

基于ffmpeg编码

  1. 编码时要先设置基本的参数

#Create an H.264 codec
codec = av.CodecContext.create(‘h264’, ‘w’)
#Get the width and height of the frame
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
#Set the codec parameters
codec.width = width
codec.height = height
codec.pix_fmt = ‘yuv420p’

  1. 编码器内部有状态, 送入一帧并不一定输出一个packet
    # Create an AVFrame and fill it with data
    av_frame = av.VideoFrame.from_ndarray(frame_rgb, format=‘rgb24’)

         # Encode the frame
         packets = codec.encode(av_frame)
    
         # Write the encoded data to the file
         for packet in packets:
             outfile.write(packet)
    
  2. 编码器的前两帧可能是PPS、SPS
    这部分是解码时的依据,比如ffplay:
    ffplay.exe -i D:\code\opensrc\cameracap\1.mcap.h264

调用opencv 编码jpeg

https://zhuanlan.zhihu.com/p/670334502

示例

def h264_mcap():
    global cap_index
    # 打开摄像头,0表示默认的摄像头
    cap = cv2.VideoCapture(0)

    # # Create an H.264 codec
    codec = av.CodecContext.create('h264', 'w')

    # Get the width and height of the frame
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    pix_fmt = 'yuv420p'
    # Set the codec parameters
    codec.width = width
    codec.height = height
    codec.pix_fmt = pix_fmt

    # Open a file to write the raw H.264 data
    with open(sys.argv[1], "wb") as f, Writer(f) as mcap_writer:
        h264_raw = open(sys.argv[1]+".h264", "wb")
        for i in range(1, 300):
            ret, frame = cap.read()
            current_time = int(time.time()*1000*1000*1000)
            cur_sec = int(time.time())
            cur_nsec = int((time.time()-cur_sec)*1000000000)
            if ret:
                # Convert the OpenCV BGR image to RGB
                frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

                # Create an AVFrame and fill it with data
                av_frame = av.VideoFrame.from_ndarray(frame_rgb, format='rgb24')

                # Encode the frame
                packets = codec.encode(av_frame)

                # Write the encoded data to the file
                for packet in packets:
                    if cap_index > 0:
                        h264_raw.write(packet)
                        print(f"write packet  {cap_index}")
                        # 将编码后的帧保存为MCAP消息
                        video_frame = CompressedVideo(format=b'h264', frame_id="camera", timestamp=Timestamp(seconds=cur_sec,nanos=cur_nsec), data=bytes(packet))
                        mcap_writer.write_message(topic="/camera_h264",sequence=cap_index, message=video_frame, log_time=current_time, publish_time=current_time)
                        cap_index = cap_index+1
                        print(f"write mcap  {cap_index}, video_frame: {len(video_frame.data)}")
                    else:
                        print(f"skip mcap  {cap_index}")
                        cap_index = cap_index+1
                # Display the result
                cv2.imshow('frame', frame)
                cv2.waitKey(10)
            else:
                break
        current_time = int(time.time()*1000*1000*1000)
        cur_sec = int(time.time())
        cur_nsec = int((time.time()-cur_sec)*1000000000)
        # Encode any remaining frames
        for packet in codec.encode():
            h264_raw.write(packet)
            print(f"flush packet  {cap_index}")
            # 将编码后的帧保存为MCAP消息
            video_frame = CompressedVideo(format=b'h264', frame_id="camera", timestamp=Timestamp(seconds=cur_sec,nanos=cur_nsec), data=bytes(packet))
            mcap_writer.write_message(topic="/camera_h264",sequence=cap_index, message=video_frame, log_time=current_time, publish_time=current_time)
            cap_index = cap_index+1   
            print(f"write mcap  {cap_index}, video_frame: {len(video_frame.data)}") 
        cap.release()
        cv2.destroyAllWindows()
        h264_raw.close()
def mjpeg_mcap():
    global cap_index
    # 打开摄像头,0表示默认的摄像头
    cap = cv2.VideoCapture(0)
    # Open a file to write the raw H.264 data
    with open(sys.argv[1], "wb") as f, Writer(f) as mcap_writer:
        h264_raw = open(sys.argv[1]+".jpegs", "wb")
        for i in range(1, 300):
            ret, frame = cap.read()
            current_time = int(time.time()*1000*1000*1000)
            cur_sec = int(time.time())
            cur_nsec = int((time.time()-cur_sec)*1000000000)
            if ret:
                enc_ret,enc_buf = cv2.imencode('.jpeg', frame)
                if enc_ret:
                    h264_raw.write(enc_buf)
                    print(f"write packet  {cap_index}")
                    # 将编码后的帧保存为MCAP消息
                    jpeg_frame = CompressedImage(format=b'image/jpeg', frame_id="camera", timestamp=Timestamp(seconds=cur_sec,nanos=cur_nsec), data=bytes(enc_buf))
                    mcap_writer.write_message(topic="/camera_jpeg",sequence=cap_index, message=jpeg_frame, log_time=current_time, publish_time=current_time)
                    cap_index = cap_index+1
                    print(f"write mcap  {cap_index}, video_frame: {len(jpeg_frame.data)}")
                    
                # Display the result
                cv2.imshow('frame', frame)
                cv2.waitKey(10)
            else:
                break
        cap.release()
        cv2.destroyAllWindows()
        h264_raw.close()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值