这是bev的WriteResultImageMessage和OnReceiveData函数：
std::unordered_map< std::string, 
                      std::shared_ptr<apollo::cyber::Writer<apollo::drivers::Image>> >
      camera_image_output_writer_;
bool BevObstacleDetectionComponent::OnReceiveData(
      BevFrame &bev_frame){
  CameraFrameSet &camera_frame_set = bev_frame.camera_frame_set;
  std::shared_ptr<apollo::perception::PerceptionObstacles> out_message(
      new (std::nothrow) apollo::perception::PerceptionObstacles);

  if (bev_frame.out_message_array.size() != 0){
    AERROR << "using existing message serialization ...";
    out_message->ParseFromArray((void *)bev_frame.out_message_array.data(), bev_frame.out_message_array.size());
    double publish_time = Clock::NowInSeconds();
    double msg_timestamp = cyber::Time::Now().ToSecond();
    apollo::common::Header *header = out_message->mutable_header();
    header->set_timestamp_sec(publish_time);
    header->set_module_name("perception_camera");
    header->set_sequence_num(++seq_num_);
    // in nanosecond
    // PnC would use lidar timestamp to predict
    header->set_lidar_timestamp(static_cast<uint64_t>(msg_timestamp * 1e9));
    header->set_camera_timestamp(static_cast<uint64_t>(msg_timestamp * 1e9));
  }else{
    apollo::common::ErrorCode error_code = apollo::common::OK;
    std::shared_ptr<SensorFrameMessage> prefused_message(new (std::nothrow)
                                                              SensorFrameMessage);
    const double msg_timestamp =
        camera_frame_set.begin()->first + timestamp_offset_;
    uint32_t cur_seq_num = ++seq_num_;

    prefused_message->seq_num_ = cur_seq_num;
    if (InternalProc(bev_frame, &error_code, prefused_message.get(),
                    out_message.get()) != cyber::SUCC) {
      AERROR << "InternalProc failed, error_code: " << error_code;
      if (MakeProtobufMsg(msg_timestamp, cur_seq_num, {}, {}, error_code,
                          out_message.get()) != cyber::SUCC) {
        AERROR << "MakeProtobufMsg failed";
        return false;
      }
      if (output_final_obstacles_) {
        writer_->Write(out_message);
      }
      return false;
    }

    // 把输出的message保存下来
    // {    
    //   int message_byte_length = out_message->ByteSize();
    //   std::vector<char> temp(message_byte_length);
    //   out_message->SerializeToArray((void *)temp.data(), message_byte_length);
    //   std::fstream out_file_stream;
    //   AERROR << "save output message : " << bev_frame.frame_dir_path + "/out_message.obs";
    //   out_file_stream.open(bev_frame.frame_dir_path + "/out_message.obs", std::ios::out | std::ios::binary);
    //   out_file_stream.write(temp.data(), message_byte_length);
    //   out_file_stream.close();
    // }     
  }

  //AERROR << "output_final_obstacles: " << output_final_obstacles_;
  if (output_final_obstacles_) {

    writer_->Write(out_message);
  }

  //AERROR << "output result image !";
  WriteResultImageMessage(camera_frame_set);
  return true;
}
int BevObstacleDetectionComponent::WriteResultImageMessage(std::map<uint64_t, BevCameraFrame> &CameraFrameSet){
  
  for (const auto &timestamp_cameraframe : CameraFrameSet){
    const auto &frame = timestamp_cameraframe.second;
    const std::string &camera_name = frame.camera_name;

    apollo::drivers::Image image_message;
    if (frame.camera_result_image == nullptr) continue;
    const auto &mat_image = *frame.camera_result_image;
    double publish_time = Clock::NowInSeconds();
    apollo::common::Header *header = image_message.mutable_header();
    header->set_timestamp_sec(publish_time);

    image_message.set_width(mat_image.cols);
    image_message.set_height(mat_image.rows);
    image_message.set_step(3 * mat_image.cols);
    image_message.set_data(mat_image.data, mat_image.size[0] * mat_image.size[1] *
                                        mat_image.channels());
    
    camera_image_output_writer_[camera_name]->Write(image_message);
  }  

  return cyber::SUCC;
}
如何将bev的WriteResultImageMessage融入到lane组件里，通过广播将已经检测出的车道线数据塞到camera_image_output_writer_里。
这是lane组件的一部分代码：
void LaneDetectionComponent::OnReceiveImage(
    const std::shared_ptr<apollo::drivers::Image> &message,
    const std::string &camera_name) {
  std::lock_guard<std::mutex> lock(mutex_);
  const double msg_timestamp = message->measurement_time() + timestamp_offset_;
  AINFO << "Enter LaneDetectionComponent::Proc(), camera_name: " << camera_name
        << " image ts: " << msg_timestamp;
  // timestamp should be almost monotonic
  if (last_timestamp_ - msg_timestamp > ts_diff_) {
    AINFO << "Received an old message. Last ts is " << std::setprecision(19)
          << last_timestamp_ << " current ts is " << msg_timestamp
          << " last - current is " << last_timestamp_ - msg_timestamp;
    return;
  }
  last_timestamp_ = msg_timestamp;
  ++seq_num_;

  // for e2e lantency statistics
  {
    const double cur_time = Clock::NowInSeconds();
    const double start_latency = (cur_time - message->measurement_time()) * 1e3;
    AINFO << "FRAME_STATISTICS:Camera:Start:msg_time[" << camera_name << "-"
          << FORMAT_TIMESTAMP(message->measurement_time()) << "]:cur_time["
          << FORMAT_TIMESTAMP(cur_time) << "]:cur_latency[" << start_latency
          << "]";
  }

  // protobuf msg
  std::shared_ptr<apollo::perception::PerceptionLanes> out_message(
      new (std::nothrow) apollo::perception::PerceptionLanes);
  apollo::common::ErrorCode error_code = apollo::common::OK;

  // prefused msg
  std::shared_ptr<SensorFrameMessage> prefused_message(new (std::nothrow)
                                                           SensorFrameMessage);
  if (InternalProc(message, camera_name, &error_code, prefused_message.get(),
                   out_message.get()) != cyber::SUCC) {
    AERROR << "InternalProc failed, error_code: " << error_code;
    return;
  }

  WriteResultImageMessage

  // for e2e lantency statistics
  {
    const double end_timestamp = Clock::NowInSeconds();
    const double end_latency =
        (end_timestamp - message->measurement_time()) * 1e3;
    AINFO << "FRAME_STATISTICS:Camera:End:msg_time[" << camera_name << "-"
          << FORMAT_TIMESTAMP(message->measurement_time()) << "]:cur_time["
          << FORMAT_TIMESTAMP(end_timestamp) << "]:cur_latency[" << end_latency
          << "]";
  }
}