5 Commits

Author SHA1 Message Date
AiYangSky
fe18e3e0b6 build done 2023-12-21 18:46:16 +08:00
AiYangSky
5d2e5b0250 code done 2023-12-21 17:33:06 +08:00
AiYangSky
9f35bf476e add G1 camera 2023-12-20 19:05:47 +08:00
AiYangSky
173acc7036 add G1 camera 2023-12-20 18:55:51 +08:00
AiYangSky
a0d3e258d9 camerabase done 2023-12-19 18:44:25 +08:00
99 changed files with 1682 additions and 3768 deletions

12
.gitignore vendored
View File

@@ -1,13 +1,6 @@
# Distribution / packaging
.Python
build/
models/
confs/
ZLM/
ZLMediaKit/
ffmpeg-4.2.5/
nv-codec-headers/
*.bz2
develop-eggs/
dist/
eggs/
@@ -22,11 +15,6 @@ share/python-wheels/
*.egg
MANIFEST
.idea/
calib_webcam_1280x720.yaml
calib_webcam_640x480.yaml
sv_algorithm_params.json
sv_algorithm_params_coco_1280.json
sv_algorithm_params_coco_640.json
# Prerequisites
*.d

View File

@@ -24,7 +24,6 @@ else()
option(USE_FFMPEG "BUILD WITH FFMPEG." ON)
elseif(PLATFORM STREQUAL "X86_INTEL")
add_definitions(-DPLATFORM_X86_INTEL)
option(USE_INTEL "BUILD WITH INTEL." ON)
option(USE_FFMPEG "BUILD WITH FFMPEG." ON)
else()
message(FATAL_ERROR "UNSUPPORTED PLATFORM!")
@@ -39,10 +38,6 @@ if(USE_CUDA)
message(STATUS "CUDA: ON")
endif()
if(USE_INTEL)
add_definitions(-DWITH_INTEL)
message(STATUS "INTEL: ON")
endif()
if(USE_GSTREAMER)
add_definitions(-DWITH_GSTREAMER)
@@ -77,9 +72,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/gimbal_ctrl/driver/src/GX40
${CMAKE_CURRENT_SOURCE_DIR}/gimbal_ctrl/driver/src
${CMAKE_CURRENT_SOURCE_DIR}/gimbal_ctrl
${CMAKE_CURRENT_SOURCE_DIR}/algorithm/common_det/intel
${CMAKE_CURRENT_SOURCE_DIR}/algorithm/landing_det/intel
${CMAKE_CURRENT_SOURCE_DIR}/algorithm/veri/intel
${CMAKE_CURRENT_SOURCE_DIR}/algorithm/common_det/cuda
${CMAKE_CURRENT_SOURCE_DIR}/algorithm/landing_det/cuda
${CMAKE_CURRENT_SOURCE_DIR}/algorithm/sot/ocv470
@@ -127,7 +119,8 @@ set(
include/sv_mot.h
include/sv_color_line.h
include/sv_veri_det.h
include/sv_video_input.h
# include/sv_video_input.h
include/sv_camera.h
include/sv_video_output.h
include/sv_world.h
)
@@ -195,23 +188,7 @@ if(USE_CUDA)
list(APPEND spirecv_SRCS ${ALG_SRC_FILES})
endif()
if(USE_INTEL)
file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/common_det/intel/*.cpp)
list(APPEND spirecv_SRCS ${ALG_SRC_FILES})
file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/landing_det/intel/*.cpp)
list(APPEND spirecv_SRCS ${ALG_SRC_FILES})
file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/veri/intel/*.cpp)
list(APPEND spirecv_SRCS ${ALG_SRC_FILES})
endif()
if(USE_FFMPEG)
if(USE_INTEL)
file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/video_io/ffmpeg/x86_intel/*.cpp)
list(APPEND spirecv_SRCS ${ALG_SRC_FILES})
elseif(USE_CUDA)
file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/video_io/ffmpeg/x86_cuda/*.cpp)
list(APPEND spirecv_SRCS ${ALG_SRC_FILES})
endif()
file(GLOB ALG_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/video_io/ffmpeg/*.cpp)
list(APPEND spirecv_SRCS ${ALG_SRC_FILES})
endif()
@@ -255,22 +232,10 @@ if(USE_CUDA) # PLATFORM_X86_CUDA & PLATFORM_JETSON
target_link_libraries(SpireCVSeg sv_world)
elseif(PLATFORM STREQUAL "X86_INTEL") # Links to Intel-OpenVINO libraries here
# Intel-Openvino
include_directories(
PUBLIC /opt/intel/openvino_2022/runtime/include/
PUBLIC /opt/intel/openvino_2022/runtime/include/ie/
)
link_directories(
${InferenceEngine_LIBRARIES}
/opt/intel/openvino_2022/runtime/lib/intel64/libopenvino.so
)
add_library(sv_world SHARED ${spirecv_SRCS})
target_link_libraries(
sv_world ${OpenCV_LIBS}
sv_gimbal
${InferenceEngine_LIBRARIES}
/opt/intel/openvino_2022/runtime/lib/intel64/libopenvino.so
)
endif()

View File

@@ -38,9 +38,9 @@ SpireCV is an **real-time edge perception SDK** built for **intelligent unmanned
- **Platform level**
- [x] X86 + Nvidia GPUs (10 series, 20 series, and 30 series graphics cards recommended)
- [x] Jetson (AGX Orin/Xavier、Orin NX/Nano、Xavier NX)
- [x] Intel CPU
- [ ] HUAWEI Ascend (coming soon)
- [ ] Intel CPU (coming soon)
- [ ] Rockchip (coming soon)
- [ ] HUAWEI Ascend (coming soon)
## Demos
- **QR code detection**

View File

@@ -38,9 +38,9 @@ SpireCV是一个专为**智能无人系统**打造的**边缘实时感知SDK**
- **平台层**
- [x] X86+Nvidia GPU推荐10系、20系、30系显卡
- [x] JetsonAGX Orin/Xavier、Orin NX/Nano、Xavier NX
- [x] Intel CPU
- [ ] HUAWEI Ascend推进中
- [ ] Intel CPU(推进中)
- [ ] Rockchip推进中
- [ ] HUAWEI Ascend推进中
## 功能展示
- **二维码检测**

View File

@@ -1,7 +1,6 @@
#include "common_det_cuda_impl.h"
#include <cmath>
#include <fstream>
#include "sv_util.h"
#define SV_MODEL_DIR "/SpireCV/models/"
#define SV_ROOT_DIR "/SpireCV/"
@@ -365,43 +364,15 @@ bool CommonObjectDetectorCUDAImpl::cudaSetup(CommonObjectDetectorBase* base_, bo
double thrs_nms = base_->getThrsNms();
std::string engine_fn = get_home() + SV_MODEL_DIR + dataset + ".engine";
std::vector<std::string> files;
_list_dir(get_home() + SV_MODEL_DIR, files, "-online.engine", dataset + "-yolov5s-");
if (files.size() > 0)
{
std::sort(files.rbegin(), files.rend(), _comp_str_lesser);
engine_fn = get_home() + SV_MODEL_DIR + files[0];
}
if (input_w == 1280)
{
files.clear();
_list_dir(get_home() + SV_MODEL_DIR, files, "-online.engine", dataset + "-yolov5s6-");
if (files.size() > 0)
{
std::sort(files.rbegin(), files.rend(), _comp_str_lesser);
engine_fn = get_home() + SV_MODEL_DIR + files[0];
}
else
{
engine_fn = get_home() + SV_MODEL_DIR + dataset + "_HD.engine";
}
engine_fn = get_home() + SV_MODEL_DIR + dataset + "_HD.engine";
}
if (with_segmentation)
{
base_->setInputH(640);
base_->setInputW(640);
files.clear();
_list_dir(get_home() + SV_MODEL_DIR, files, "-online.engine", dataset + "-yolov5s-seg-");
if (files.size() > 0)
{
std::sort(files.rbegin(), files.rend(), _comp_str_lesser);
engine_fn = get_home() + SV_MODEL_DIR + files[0];
}
else
{
engine_fn = get_home() + SV_MODEL_DIR + dataset + "_SEG.engine";
}
engine_fn = get_home() + SV_MODEL_DIR + dataset + "_SEG.engine";
}
std::cout << "Load: " << engine_fn << std::endl;
if (!is_file_exist(engine_fn))

View File

@@ -1,449 +0,0 @@
#include "common_det_intel_impl.h"
#include <cmath>
#include <fstream>
#define SV_MODEL_DIR "/SpireCV/models/"
#define SV_ROOT_DIR "/SpireCV/"
namespace sv
{
#ifdef WITH_INTEL
using namespace cv;
using namespace std;
using namespace dnn;
#endif
float sigmoid_function(float a)
{
float b = 1. / (1. + exp(-a));
return b;
}
cv::Mat letterbox(cv::Mat &img_, std::vector<float> &paddings)
{
std::vector<int> new_shape = {640, 640};
// Get current image shape [height, width]
int img_h = img_.rows;
int img_w = img_.cols;
// Compute scale ratio(new / old) and target resized shape
float scale = std::min(new_shape[1] * 1.0 / img_h, new_shape[0] * 1.0 / img_w);
int resize_h = int(round(img_h * scale));
int resize_w = int(round(img_w * scale));
paddings[0] = scale;
// Compute padding
int pad_h = new_shape[1] - resize_h;
int pad_w = new_shape[0] - resize_w;
// Resize and pad image while meeting stride-multiple constraints
cv::Mat resized_img;
cv::resize(img_, resized_img, cv::Size(resize_w, resize_h));
// divide padding into 2 sides
float half_h = pad_h * 1.0 / 2;
float half_w = pad_w * 1.0 / 2;
paddings[1] = half_h;
paddings[2] = half_w;
// Compute padding boarder
int top = int(round(half_h - 0.1));
int bottom = int(round(half_h + 0.1));
int left = int(round(half_w - 0.1));
int right = int(round(half_w + 0.1));
// Add border
cv::copyMakeBorder(resized_img, resized_img, top, bottom, left, right, 0, cv::Scalar(114, 114, 114));
return resized_img;
}
CommonObjectDetectorIntelImpl::CommonObjectDetectorIntelImpl()
{
}
CommonObjectDetectorIntelImpl::~CommonObjectDetectorIntelImpl()
{
}
void CommonObjectDetectorIntelImpl::intelDetect(
CommonObjectDetectorBase *base_,
cv::Mat img_,
std::vector<float> &boxes_x_,
std::vector<float> &boxes_y_,
std::vector<float> &boxes_w_,
std::vector<float> &boxes_h_,
std::vector<int> &boxes_label_,
std::vector<float> &boxes_score_,
std::vector<cv::Mat> &boxes_seg_,
bool input_4k_)
{
#ifdef WITH_INTEL
int input_h = base_->getInputH();
int input_w = base_->getInputW();
bool with_segmentation = base_->withSegmentation();
double thrs_conf = base_->getThrsConf();
double thrs_nms = base_->getThrsNms();
if (with_segmentation)
{
std::vector<float> paddings(3); // scale, half_h, half_w
this->preprocess_img_seg(img_, paddings);
infer_request.start_async();
infer_request.wait();
// Postprocess
this->postprocess_img_seg(img_, paddings, boxes_x_, boxes_y_, boxes_w_, boxes_h_, boxes_label_, boxes_score_, boxes_seg_, thrs_conf, thrs_nms);
}
else
{
// Preprocess
this->preprocess_img(img_);
// Run inference
infer_request.start_async();
infer_request.wait();
// Postprocess
this->postprocess_img(boxes_x_, boxes_y_, boxes_w_, boxes_h_, boxes_label_, boxes_score_, thrs_conf, thrs_nms);
}
#endif
}
bool CommonObjectDetectorIntelImpl::intelSetup(CommonObjectDetectorBase *base_, bool input_4k_)
{
#ifdef WITH_INTEL
ov::Core core;
std::string dataset = base_->getDataset();
double thrs_conf = base_->getThrsConf();
double thrs_nms = base_->getThrsNms();
inpHeight = base_->getInputH();
inpWidth = base_->getInputW();
with_segmentation = base_->withSegmentation();
std::string openvino_fn = get_home() + SV_MODEL_DIR + dataset + ".onnx";
if (inpWidth == 1280)
{
openvino_fn = get_home() + SV_MODEL_DIR + dataset + "_HD.onnx";
}
if (with_segmentation)
{
base_->setInputH(640);
base_->setInputW(640);
openvino_fn = get_home() + SV_MODEL_DIR + dataset + "_SEG.onnx";
}
std::cout << "Load: " << openvino_fn << std::endl;
if (!is_file_exist(openvino_fn))
{
throw std::runtime_error("SpireCV (104) Error loading the CommonObject OpenVINO model (File Not Exist)");
}
if (input_4k_ && with_segmentation)
{
throw std::runtime_error("SpireCV (106) Resolution 4K DO NOT Support Segmentation!");
}
if (with_segmentation)
{
this->compiled_model = core.compile_model(openvino_fn, "GPU");
this->infer_request = compiled_model.create_infer_request();
}
else
{
std::shared_ptr<ov::Model> model_ = core.read_model(openvino_fn);
ov::preprocess::PrePostProcessor Pre_P = ov::preprocess::PrePostProcessor(model_);
Pre_P.input().tensor().set_element_type(ov::element::u8).set_layout("NHWC").set_color_format(ov::preprocess::ColorFormat::RGB);
Pre_P.input().preprocess().convert_element_type(ov::element::f32).convert_color(ov::preprocess::ColorFormat::RGB).scale({255, 255, 255}); // .scale({ 112, 112, 112 });
Pre_P.input().model().set_layout("NCHW");
Pre_P.output().tensor().set_element_type(ov::element::f32);
model_ = Pre_P.build();
this->compiled_model = core.compile_model(model_, "GPU");
this->infer_request = compiled_model.create_infer_request();
}
return true;
#endif
return false;
}
void CommonObjectDetectorIntelImpl::preprocess_img(cv::Mat &img_)
{
#ifdef WITH_INTEL
float width = img_.cols;
float height = img_.rows;
cv::Size new_shape = cv::Size(inpHeight, inpWidth);
float r = float(new_shape.width / max(width, height));
int new_unpadW = int(round(width * r));
int new_unpadH = int(round(height * r));
cv::resize(img_, resize.resized_image, cv::Size(new_unpadW, new_unpadH), 0, 0, cv::INTER_AREA);
resize.resized_image = resize.resized_image;
resize.dw = new_shape.width - new_unpadW;
resize.dh = new_shape.height - new_unpadH;
cv::Scalar color = cv::Scalar(100, 100, 100);
cv::copyMakeBorder(resize.resized_image, resize.resized_image, 0, resize.dh, 0, resize.dw, cv::BORDER_CONSTANT, color);
this->rx = (float)img_.cols / (float)(resize.resized_image.cols - resize.dw);
this->ry = (float)img_.rows / (float)(resize.resized_image.rows - resize.dh);
if (with_segmentation)
{
cv::Mat blob = cv::dnn::blobFromImage(resize.resized_image, 1 / 255.0, cv::Size(640, 640), cv::Scalar(0, 0, 0), true);
auto input_port = compiled_model.input();
ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), blob.ptr(0));
infer_request.set_input_tensor(input_tensor);
}
else
{
float *input_data = (float *)resize.resized_image.data;
input_tensor = ov::Tensor(compiled_model.input().get_element_type(), compiled_model.input().get_shape(), input_data);
infer_request.set_input_tensor(input_tensor);
}
#endif
}
void CommonObjectDetectorIntelImpl::preprocess_img_seg(cv::Mat &img_, std::vector<float> &paddings)
{
#ifdef WITH_INTEL
cv::Mat masked_img;
cv::Mat resized_img = letterbox(img_, paddings); // resize to (640,640) by letterbox
// BGR->RGB, u8(0-255)->f32(0.0-1.0), HWC->NCHW
cv::Mat blob = cv::dnn::blobFromImage(resized_img, 1 / 255.0, cv::Size(640, 640), cv::Scalar(0, 0, 0), true);
// Get input port for model with one input
auto input_port = compiled_model.input();
// Create tensor from external memory
ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), blob.ptr(0));
// Set input tensor for model with one input
infer_request.set_input_tensor(input_tensor);
#endif
}
void CommonObjectDetectorIntelImpl::postprocess_img_seg(cv::Mat &img_,
std::vector<float> &paddings,
std::vector<float> &boxes_x_,
std::vector<float> &boxes_y_,
std::vector<float> &boxes_w_,
std::vector<float> &boxes_h_,
std::vector<int> &boxes_label_,
std::vector<float> &boxes_score_,
std::vector<cv::Mat> &boxes_seg_,
double &thrs_conf,
double &thrs_nms)
{
#ifdef WITH_INTEL
const ov::Tensor &detect = infer_request.get_output_tensor(0);
ov::Shape detect_shape = detect.get_shape();
const ov::Tensor &proto = infer_request.get_output_tensor(1);
ov::Shape proto_shape = proto.get_shape();
cv::Mat detect_buffer(detect_shape[1], detect_shape[2], CV_32F, detect.data());
cv::Mat proto_buffer(proto_shape[1], proto_shape[2] * proto_shape[3], CV_32F, proto.data());
cv::RNG rng;
float conf_threshold = thrs_conf;
float nms_threshold = thrs_nms;
std::vector<cv::Rect> boxes;
std::vector<int> class_ids;
std::vector<float> class_scores;
std::vector<float> confidences;
std::vector<cv::Mat> masks;
float scale = paddings[0];
for (int i = 0; i < detect_buffer.rows; i++)
{
float confidence = detect_buffer.at<float>(i, 4);
if (confidence < conf_threshold)
{
continue;
}
cv::Mat classes_scores = detect_buffer.row(i).colRange(5, 85);
cv::Point class_id;
double score;
cv::minMaxLoc(classes_scores, NULL, &score, NULL, &class_id);
// class score: 0~1
if (score > 0.25)
{
cv::Mat mask = detect_buffer.row(i).colRange(85, 117);
float cx = detect_buffer.at<float>(i, 0);
float cy = detect_buffer.at<float>(i, 1);
float w = detect_buffer.at<float>(i, 2);
float h = detect_buffer.at<float>(i, 3);
int left = static_cast<int>((cx - 0.5 * w - paddings[2]) / scale);
int top = static_cast<int>((cy - 0.5 * h - paddings[1]) / scale);
int width = static_cast<int>(w / scale);
int height = static_cast<int>(h / scale);
cv::Rect box;
box.x = left;
box.y = top;
box.width = width;
box.height = height;
boxes.push_back(box);
class_ids.push_back(class_id.x);
class_scores.push_back(score);
confidences.push_back(confidence);
masks.push_back(mask);
}
}
// NMS
std::vector<int> indices;
cv::dnn::NMSBoxes(boxes, confidences, thrs_conf, thrs_nms, indices);
// cv::Mat rgb_mask;
cv::Mat rgb_mask = cv::Mat::zeros(img_.size(), img_.type());
for (size_t i = 0; i < indices.size(); i++)
{
int index = indices[i];
int class_id = class_ids[index];
cv::Rect box = boxes[index];
int x1 = std::max(0, box.x);
int y1 = std::max(0, box.y);
int x2 = std::max(0, box.br().x);
int y2 = std::max(0, box.br().y);
cv::Mat m = masks[index] * proto_buffer;
for (int col = 0; col < m.cols; col++)
{
m.at<float>(0, col) = sigmoid_function(m.at<float>(0, col));
}
cv::Mat m1 = m.reshape(1, 160); // 1x25600 -> 160x160
int mx1 = std::max(0, int((x1 * scale + paddings[2]) * 0.25));
int mx2 = std::max(0, int((x2 * scale + paddings[2]) * 0.25));
int my1 = std::max(0, int((y1 * scale + paddings[1]) * 0.25));
int my2 = std::max(0, int((y2 * scale + paddings[1]) * 0.25));
cv::Mat mask_roi = m1(cv::Range(my1, my2), cv::Range(mx1, mx2));
cv::Mat rm, det_mask;
cv::resize(mask_roi, rm, cv::Size(x2 - x1, y2 - y1));
for (int r = 0; r < rm.rows; r++)
{
for (int c = 0; c < rm.cols; c++)
{
float pv = rm.at<float>(r, c);
if (pv > 0.5)
{
rm.at<float>(r, c) = 1.0;
}
else
{
rm.at<float>(r, c) = 0.0;
}
}
}
rm = rm * rng.uniform(0, 255);
rm.convertTo(det_mask, CV_8UC1);
if ((y1 + det_mask.rows) >= img_.rows)
{
y2 = img_.rows - 1;
}
if ((x1 + det_mask.cols) >= img_.cols)
{
x2 = img_.cols - 1;
}
cv::Mat mask = cv::Mat::zeros(cv::Size(img_.cols, img_.rows), CV_8UC1);
det_mask(cv::Range(0, y2 - y1), cv::Range(0, x2 - x1)).copyTo(mask(cv::Range(y1, y2), cv::Range(x1, x2)));
add(rgb_mask, cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), rgb_mask, mask);
boxes_x_.push_back(box.x);
boxes_y_.push_back(box.y);
boxes_w_.push_back(box.width);
boxes_h_.push_back(box.height);
boxes_label_.push_back((int)class_id);
boxes_score_.push_back(class_scores[index]);
cv::Mat mask_j = mask.clone();
boxes_seg_.push_back(mask_j);
}
#endif
}
void CommonObjectDetectorIntelImpl::postprocess_img(std::vector<float> &boxes_x_,
std::vector<float> &boxes_y_,
std::vector<float> &boxes_w_,
std::vector<float> &boxes_h_,
std::vector<int> &boxes_label_,
std::vector<float> &boxes_score_,
double &thrs_conf,
double &thrs_nms)
{
#ifdef WITH_INTEL
const ov::Tensor &output_tensor = infer_request.get_output_tensor();
ov::Shape output_shape = output_tensor.get_shape();
float *detections = output_tensor.data<float>();
std::vector<cv::Rect> boxes;
vector<int> class_ids;
vector<float> confidences;
for (int i = 0; i < output_shape[1]; i++)
{
float *detection = &detections[i * output_shape[2]];
float confidence = detection[4];
if (confidence >= thrs_conf)
{
float *classes_scores = &detection[5];
cv::Mat scores(1, output_shape[2] - 5, CV_32FC1, classes_scores);
cv::Point class_id;
double max_class_score;
cv::minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
if (max_class_score > thrs_conf)
{
confidences.push_back(confidence);
class_ids.push_back(class_id.x);
float x = detection[0];
float y = detection[1];
float w = detection[2];
float h = detection[3];
float xmin = x - (w / 2);
float ymin = y - (h / 2);
boxes.push_back(cv::Rect(xmin, ymin, w, h));
}
}
}
std::vector<int> nms_result;
cv::dnn::NMSBoxes(boxes, confidences, thrs_conf, thrs_nms, nms_result);
std::vector<Detection> output;
for (int i = 0; i < nms_result.size(); i++)
{
Detection result;
int idx = nms_result[i];
result.class_id = class_ids[idx];
result.confidence = confidences[idx];
result.box = boxes[idx];
output.push_back(result);
}
for (int i = 0; i < output.size(); i++)
{
auto detection = output[i];
auto box = detection.box;
auto classId = detection.class_id;
auto confidence = detection.confidence;
float xmax = box.x + box.width;
float ymax = box.y + box.height;
boxes_x_.push_back(this->rx * box.x);
boxes_y_.push_back(this->ry * box.y);
boxes_w_.push_back(this->rx * box.width);
boxes_h_.push_back(this->ry * box.height);
boxes_label_.push_back((int)detection.class_id);
boxes_score_.push_back(detection.confidence);
}
#endif
}
}

View File

@@ -1,89 +0,0 @@
#ifndef __SV_COMMON_DET_INTEL__
#define __SV_COMMON_DET_INTEL__
#include "sv_core.h"
#include <string>
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <string>
#include <chrono>
#ifdef WITH_INTEL
#include <openvino/openvino.hpp>
#endif
struct Resize
{
cv::Mat resized_image;
int dw;
int dh;
};
struct Detection
{
int class_id;
float confidence;
cv::Rect box;
};
namespace sv
{
class CommonObjectDetectorIntelImpl
{
public:
CommonObjectDetectorIntelImpl();
~CommonObjectDetectorIntelImpl();
bool intelSetup(CommonObjectDetectorBase *base_, bool input_4k_);
void intelDetect(
CommonObjectDetectorBase *base_,
cv::Mat img_,
std::vector<float> &boxes_x_,
std::vector<float> &boxes_y_,
std::vector<float> &boxes_w_,
std::vector<float> &boxes_h_,
std::vector<int> &boxes_label_,
std::vector<float> &boxes_score_,
std::vector<cv::Mat> &boxes_seg_,
bool input_4k_);
void preprocess_img(cv::Mat &img_);
void preprocess_img_seg(cv::Mat &img_, std::vector<float> &paddings);
void postprocess_img_seg(cv::Mat &img_,
std::vector<float> &paddings,
std::vector<float> &boxes_x_,
std::vector<float> &boxes_y_,
std::vector<float> &boxes_w_,
std::vector<float> &boxes_h_,
std::vector<int> &boxes_label_,
std::vector<float> &boxes_score_,
std::vector<cv::Mat> &boxes_seg_,
double &thrs_conf,
double &thrs_nms);
void postprocess_img(std::vector<float> &boxes_x_,
std::vector<float> &boxes_y_,
std::vector<float> &boxes_w_,
std::vector<float> &boxes_h_,
std::vector<int> &boxes_label_,
std::vector<float> &boxes_score_,
double &thrs_conf,
double &thrs_nms);
#ifdef WITH_INTEL
int inpWidth;
int inpHeight;
bool with_segmentation;
float rx; // the width ratio of original image and resized image
float ry; // the height ratio of original image and resized image
Resize resize;
ov::Tensor input_tensor;
ov::InferRequest infer_request;
ov::CompiledModel compiled_model;
#endif
};
}
#endif

View File

@@ -8,10 +8,6 @@
#include "common_det_cuda_impl.h"
#endif
#ifdef WITH_INTEL
#include <openvino/openvino.hpp>
#include "common_det_intel_impl.h"
#endif
namespace sv {
@@ -22,10 +18,6 @@ CommonObjectDetector::CommonObjectDetector(bool input_4k)
#ifdef WITH_CUDA
this->_cuda_impl = new CommonObjectDetectorCUDAImpl;
#endif
#ifdef WITH_INTEL
this->_intel_impl = new CommonObjectDetectorIntelImpl;
#endif
}
CommonObjectDetector::~CommonObjectDetector()
{
@@ -36,10 +28,6 @@ bool CommonObjectDetector::setupImpl()
#ifdef WITH_CUDA
return this->_cuda_impl->cudaSetup(this, this->_input_4k);
#endif
#ifdef WITH_INTEL
return this->_intel_impl->intelSetup(this, this->_input_4k);
#endif
return false;
}
@@ -65,23 +53,14 @@ void CommonObjectDetector::detectImpl(
boxes_label_,
boxes_score_,
boxes_seg_,
this->_input_4k);
#endif
#ifdef WITH_INTEL
this->_intel_impl->intelDetect(
this,
img_,
boxes_x_,
boxes_y_,
boxes_w_,
boxes_h_,
boxes_label_,
boxes_score_,
boxes_seg_,
this->_input_4k);
this->_input_4k
);
#endif
}
}

View File

@@ -1,7 +1,6 @@
#include "landing_det_cuda_impl.h"
#include <cmath>
#include <fstream>
#include "sv_util.h"
#define SV_MODEL_DIR "/SpireCV/models/"
#define SV_ROOT_DIR "/SpireCV/"
@@ -51,16 +50,6 @@ bool LandingMarkerDetectorCUDAImpl::cudaSetup()
{
#ifdef WITH_CUDA
std::string trt_model_fn = get_home() + SV_MODEL_DIR + "LandingMarker.engine";
std::vector<std::string> files;
_list_dir(get_home() + SV_MODEL_DIR, files, "-online.engine", "LandingMarker-");
if (files.size() > 0)
{
std::sort(files.rbegin(), files.rend(), _comp_str_lesser);
trt_model_fn = get_home() + SV_MODEL_DIR + files[0];
}
std::cout << "Load: " << trt_model_fn << std::endl;
if (!is_file_exist(trt_model_fn))
{
throw std::runtime_error("SpireCV (104) Error loading the LandingMarker TensorRT model (File Not Exist)");

View File

@@ -1,95 +0,0 @@
#include "landing_det_intel_impl.h"
#include <cmath>
#include <fstream>
#define SV_MODEL_DIR "/SpireCV/models/"
#define SV_ROOT_DIR "/SpireCV/"
namespace sv
{
#ifdef WITH_INTEL
using namespace cv;
using namespace std;
using namespace dnn;
#endif
LandingMarkerDetectorIntelImpl::LandingMarkerDetectorIntelImpl()
{
}
LandingMarkerDetectorIntelImpl::~LandingMarkerDetectorIntelImpl()
{
}
bool LandingMarkerDetectorIntelImpl::intelSetup()
{
#ifdef WITH_INTEL
std::string onnx_model_fn = get_home() + SV_MODEL_DIR + "LandingMarker.onnx";
if (!is_file_exist(onnx_model_fn))
{
throw std::runtime_error("SpireCV (104) Error loading the LandingMarker ONNX model (File Not Exist)");
}
// OpenVINO
ov::Core core;
std::shared_ptr<ov::Model> model = core.read_model(onnx_model_fn);
ov::preprocess::PrePostProcessor ppp = ov::preprocess::PrePostProcessor(model);
ppp.input().tensor().set_element_type(ov::element::u8).set_layout("NHWC").set_color_format(ov::preprocess::ColorFormat::RGB);
ppp.input().preprocess().convert_element_type(ov::element::f32).convert_color(ov::preprocess::ColorFormat::RGB).scale({255, 255, 255}); // .scale({ 112, 112, 112 });
ppp.input().model().set_layout("NCHW");
ppp.output().tensor().set_element_type(ov::element::f32);
model = ppp.build();
this->compiled_model = core.compile_model(model, "GPU");
this->infer_request = compiled_model.create_infer_request();
return true;
#endif
return false;
}
void LandingMarkerDetectorIntelImpl::intelRoiCNN(
std::vector<cv::Mat> &input_rois_,
std::vector<int> &output_labels_)
{
#ifdef WITH_INTEL
output_labels_.clear();
for (int i = 0; i < input_rois_.size(); i++)
{
cv::Mat e_roi = input_rois_[i];
// Get input port for model with one input
auto input_port = compiled_model.input();
// Create tensor from external memory
ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), e_roi.ptr(0));
// Set input tensor for model with one input
infer_request.set_input_tensor(input_tensor);
//preprocess_img(e_roi);
// infer_request.infer();
infer_request.start_async();
infer_request.wait();
const ov::Tensor &output_tensor = infer_request.get_output_tensor();
ov::Shape output_shape = output_tensor.get_shape();
this->_p_prob = output_tensor.data<float>();
// Find max index
double max = 0;
int label = 0;
for (int i = 0; i < 11; ++i)
{
if (max < this->_p_prob[i])
{
max = this->_p_prob[i];
label = i;
}
}
output_labels_.push_back(label);
}
#endif
}
}

View File

@@ -1,37 +0,0 @@
#ifndef __SV_LANDING_DET_INTEL__
#define __SV_LANDING_DET_INTEL__
#include "sv_core.h"
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/tracking.hpp>
#include <string>
#include <chrono>
#ifdef WITH_INTEL
#include <openvino/openvino.hpp>
#endif
namespace sv
{
class LandingMarkerDetectorIntelImpl
{
public:
LandingMarkerDetectorIntelImpl();
~LandingMarkerDetectorIntelImpl();
bool intelSetup();
void intelRoiCNN(
std::vector<cv::Mat> &input_rois_,
std::vector<int> &output_labels_);
#ifdef WITH_INTEL
float *_p_prob;
ov::Tensor input_tensor;
ov::InferRequest infer_request;
ov::CompiledModel compiled_model;
#endif
};
}
#endif

View File

@@ -7,10 +7,6 @@
#include "landing_det_cuda_impl.h"
#endif
#ifdef WITH_INTEL
#include <openvino/openvino.hpp>
#include "landing_det_intel_impl.h"
#endif
namespace sv {
@@ -20,10 +16,6 @@ LandingMarkerDetector::LandingMarkerDetector()
#ifdef WITH_CUDA
this->_cuda_impl = new LandingMarkerDetectorCUDAImpl;
#endif
#ifdef WITH_INTEL
this->_intel_impl = new LandingMarkerDetectorIntelImpl;
#endif
}
LandingMarkerDetector::~LandingMarkerDetector()
{
@@ -34,10 +26,6 @@ bool LandingMarkerDetector::setupImpl()
#ifdef WITH_CUDA
return this->_cuda_impl->cudaSetup();
#endif
#ifdef WITH_INTEL
return this->_intel_impl->intelSetup();
#endif
return false;
}
@@ -52,13 +40,11 @@ void LandingMarkerDetector::roiCNN(
output_labels_
);
#endif
#ifdef WITH_INTEL
this->_intel_impl->intelRoiCNN(
input_rois_,
output_labels_
);
#endif
}
}
}

View File

@@ -1,7 +1,6 @@
#include "sot_ocv470_impl.h"
#include <cmath>
#include <fstream>
#include "sv_util.h"
#define SV_MODEL_DIR "/SpireCV/models/"
#define SV_ROOT_DIR "/SpireCV/"
@@ -31,39 +30,9 @@ bool SingleObjectTrackerOCV470Impl::ocv470Setup(SingleObjectTrackerBase* base_)
std::string net = get_home() + SV_MODEL_DIR + "dasiamrpn_model.onnx";
std::string kernel_cls1 = get_home() + SV_MODEL_DIR + "dasiamrpn_kernel_cls1.onnx";
std::string kernel_r1 = get_home() + SV_MODEL_DIR + "dasiamrpn_kernel_r1.onnx";
std::vector<std::string> files1, files2, files3;
_list_dir(get_home() + SV_MODEL_DIR, files1, "-online.engine", "DaSiamRPN-Model-");
_list_dir(get_home() + SV_MODEL_DIR, files2, "-online.engine", "DaSiamRPN-Kernel-CLS1-");
_list_dir(get_home() + SV_MODEL_DIR, files3, "-online.engine", "DaSiamRPN-Kernel-R1-");
if (files1.size() > 0 && files2.size() > 0 && files3.size() > 0)
{
std::sort(files1.rbegin(), files1.rend(), _comp_str_lesser);
std::sort(files2.rbegin(), files2.rend(), _comp_str_lesser);
std::sort(files3.rbegin(), files3.rend(), _comp_str_lesser);
net = get_home() + SV_MODEL_DIR + files1[0];
kernel_cls1 = get_home() + SV_MODEL_DIR + files2[0];
kernel_r1 = get_home() + SV_MODEL_DIR + files3[0];
}
std::cout << "Load: " << net << std::endl;
std::cout << "Load: " << kernel_cls1 << std::endl;
std::cout << "Load: " << kernel_r1 << std::endl;
std::string backbone = get_home() + SV_MODEL_DIR + "nanotrack_backbone_sim.onnx";
std::string neckhead = get_home() + SV_MODEL_DIR + "nanotrack_head_sim.onnx";
std::vector<std::string> files4, files5;
_list_dir(get_home() + SV_MODEL_DIR, files4, "-online.engine", "NanoTrack-Backbone-SIM-");
_list_dir(get_home() + SV_MODEL_DIR, files5, "-online.engine", "NanoTrack-Head-SIM-");
if (files4.size() > 0 && files5.size() > 0)
{
std::sort(files4.rbegin(), files4.rend(), _comp_str_lesser);
std::sort(files5.rbegin(), files5.rend(), _comp_str_lesser);
backbone = get_home() + SV_MODEL_DIR + files4[0];
neckhead = get_home() + SV_MODEL_DIR + files5[0];
}
std::cout << "Load: " << backbone << std::endl;
std::cout << "Load: " << neckhead << std::endl;
try
{

View File

@@ -32,7 +32,7 @@ CameraAlgorithm::CameraAlgorithm()
// this->_allocator = NULL;
this->_t0 = std::chrono::system_clock::now();
this->alg_params_fn = _get_home() + SV_ROOT_DIR + "params/a-params/sv_algorithm_params.json";
this->alg_params_fn = _get_home() + SV_ROOT_DIR + "sv_algorithm_params.json";
// std::cout << "CameraAlgorithm->alg_params_fn: " << this->alg_params_fn << std::endl;
// if (_is_file_exist(params_fn))
// this->loadAlgorithmParams(params_fn);
@@ -80,12 +80,6 @@ ArucoDetector::ArucoDetector()
}
void ArucoDetector::getIdsWithLengths(std::vector<int>& ids_, std::vector<double>& lengths_)
{
ids_ = this->_ids_need;
lengths_ = this->_lengths_need;
}
void ArucoDetector::_load()
{
JsonValue all_value;
@@ -1002,11 +996,6 @@ void CommonObjectDetectorBase::detect(cv::Mat img_, TargetsInFrame& tgts_, Box*
if (this->_with_segmentation)
{
cv::Mat mask_j = boxes_seg[j].clone();
#ifdef WITH_INTEL
tgt.setMask(mask_j);
#endif
#ifdef WITH_CUDA
int maskh = mask_j.rows, maskw = mask_j.cols;
assert(maskh == maskw);
@@ -1036,7 +1025,6 @@ void CommonObjectDetectorBase::detect(cv::Mat img_, TargetsInFrame& tgts_, Box*
{
tgt.setMask(mask_j);
}
#endif
}
tgts_.targets.push_back(tgt);

View File

@@ -1,7 +1,6 @@
#include "veri_det_cuda_impl.h"
#include <cmath>
#include <fstream>
#include "sv_util.h"
#define SV_MODEL_DIR "/SpireCV/models/"
#define SV_ROOT_DIR "/SpireCV/"
@@ -76,16 +75,6 @@ namespace sv
{
#ifdef WITH_CUDA
std::string trt_model_fn = get_home() + SV_MODEL_DIR + "veri.engine";
std::vector<std::string> files;
_list_dir(get_home() + SV_MODEL_DIR, files, "-online.engine", "VERI-");
if (files.size() > 0)
{
std::sort(files.rbegin(), files.rend(), _comp_str_lesser);
trt_model_fn = get_home() + SV_MODEL_DIR + files[0];
}
std::cout << "Load: " << trt_model_fn << std::endl;
if (!is_file_exist(trt_model_fn))
{
throw std::runtime_error("SpireCV (104) Error loading the VeriDetector TensorRT model (File Not Exist)");

View File

@@ -1,112 +0,0 @@
#include "veri_det_intel_impl.h"
#include <cmath>
#include <fstream>
#define SV_MODEL_DIR "/SpireCV/models/"
#define SV_ROOT_DIR "/SpireCV/"
#include <iostream>
#include <cmath>
int BAT = 1;
float cosineSimilarity(float *vec1, float *vec2, int size)
{
// 计算向量的点积
float dotProduct = 0.0f;
for (int i = 0; i < size; ++i)
{
dotProduct += vec1[i] * vec2[i];
}
// 计算向量的模长
float magnitudeVec1 = 0.0f;
float magnitudeVec2 = 0.0f;
for (int i = 0; i < size; ++i)
{
magnitudeVec1 += vec1[i] * vec1[i];
magnitudeVec2 += vec2[i] * vec2[i];
}
magnitudeVec1 = std::sqrt(magnitudeVec1);
magnitudeVec2 = std::sqrt(magnitudeVec2);
// 计算余弦相似性
float similarity = dotProduct / (magnitudeVec1 * magnitudeVec2);
return similarity;
}
namespace sv
{
#ifdef WITH_INTEL
using namespace cv;
using namespace std;
using namespace dnn;
#endif
VeriDetectorIntelImpl::VeriDetectorIntelImpl()
{
}
VeriDetectorIntelImpl::~VeriDetectorIntelImpl()
{
}
bool VeriDetectorIntelImpl::intelSetup()
{
#ifdef WITH_INTEL
std::string onnx_model_fn = get_home() + SV_MODEL_DIR + "veri.onnx";
if (!is_file_exist(onnx_model_fn))
{
throw std::runtime_error("SpireCV (104) Error loading the VeriDetector openVINO model (File Not Exist)");
}
// OpenVINO
ov::Core core;
this->compiled_model = core.compile_model(onnx_model_fn, "GPU");
this->infer_request = compiled_model.create_infer_request();
return true;
#endif
return false;
}
void VeriDetectorIntelImpl::intelRoiCNN(
std::vector<cv::Mat> &input_rois_,
std::vector<float> &output_labels_)
{
#ifdef WITH_INTEL
Mat blobs;
blobFromImages(input_rois_, blobs, 1 / 255.0, Size(224, 224), Scalar(0, 0, 0), true, true);
auto input_port = compiled_model.input();
ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), blobs.ptr(0));
infer_request.infer();
const ov::Tensor &label_pre = infer_request.get_output_tensor(0);
this->_p_prob1 = label_pre.data<float>();
const ov::Tensor &proto_pre = infer_request.get_output_tensor(1);
this->_p_prob2 = proto_pre.data<float>();
// Find max index
double max = 0;
int label = 0;
for (int i = 0; i < 576; ++i)
{
if (max < this->_p_prob1[i])
{
max = this->_p_prob1[i];
label = i;
}
}
float similarity = cosineSimilarity(this->_p_prob2, this->_p_prob2 + 1280, 1280);
output_labels_.push_back(label);
output_labels_.push_back(similarity);
#endif
}
}

View File

@@ -1,41 +0,0 @@
#ifndef __SV_VERI_DET_INTEL__
#define __SV_VERI_DET_INTEL__
#include "sv_core.h"
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/tracking.hpp>
#include <string>
#include <chrono>
#ifdef WITH_INTEL
#include <openvino/openvino.hpp>
#endif
namespace sv
{
class VeriDetectorIntelImpl
{
public:
VeriDetectorIntelImpl();
~VeriDetectorIntelImpl();
bool intelSetup();
void intelRoiCNN(
std::vector<cv::Mat> &input_rois_,
std::vector<float> &output_labels_);
#ifdef WITH_INTEL
float *_p_data;
float *_p_prob1;
float *_p_prob2;
ov::Tensor input_tensor;
ov::InferRequest infer_request;
ov::CompiledModel compiled_model;
#endif
};
}
#endif

View File

@@ -10,11 +10,6 @@
#include "veri_det_cuda_impl.h"
#endif
#ifdef WITH_INTEL
#include <openvino/openvino.hpp>
#include "veri_det_intel_impl.h"
#endif
#define SV_ROOT_DIR "/SpireCV/"
namespace sv
@@ -25,10 +20,6 @@ namespace sv
#ifdef WITH_CUDA
this->_cuda_impl = new VeriDetectorCUDAImpl;
#endif
#ifdef WITH_INTEL
this->_intel_impl = new VeriDetectorIntelImpl;
#endif
}
VeriDetector::~VeriDetector()
{
@@ -59,9 +50,6 @@ namespace sv
return this->_cuda_impl->cudaSetup();
#endif
#ifdef WITH_INTEL
return this->_intel_impl->intelSetup();
#endif
return false;
}
@@ -75,12 +63,6 @@ namespace sv
input_rois_,
output_labels_);
#endif
#ifdef WITH_INTEL
this->_intel_impl->intelRoiCNN(
input_rois_,
output_labels_);
#endif
}
void VeriDetector::detect(cv::Mat img_, const cv::Rect &bounding_box_, sv::Target &tgt)
@@ -112,23 +94,26 @@ namespace sv
cv::Mat img_ground = cv::imread(img_ground_dir);
cv::resize(img_ground, img_ground, cv::Size(224, 224));
std::vector<cv::Mat> input_rois_ = {crop, img_ground};
std::vector<float> output_labels;
#ifdef WITH_CUDA
roiCNN(input_rois_, output_labels);
#endif
#ifdef WITH_INTEL
#ifdef WITH_CUDA
std::vector<float> output_labels;
roiCNN(input_rois_, output_labels);
#endif
// auto t1 = std::chrono::system_clock::now();
// tgts_.setFPS(1000.0 / std::chrono::duration_cast<std::chrono::milliseconds>(t1 - this->_t0).count());
// this->_t0 = std::chrono::system_clock::now();
// tgts_.setTimeNow();
if (output_labels.size() > 0)
{
// tgt.category_id = output_labels[0];
tgt.sim_score = output_labels[1];
// tgts_.targets.push_back(tgt);
}
#endif
}
void VeriDetector::getSubwindow(cv::Mat &dstCrop, cv::Mat &srcImg, int originalSz, int resizeSz)
void VeriDetector::getSubwindow(cv::Mat &dstCrop, cv::Mat &srcImg, int originalSz, int resizeSz)
{
cv::Scalar avgChans = mean(srcImg);
cv::Size imgSz = srcImg.size();

View File

@@ -46,7 +46,6 @@ class ArucoDetector : public CameraAlgorithm
public:
ArucoDetector();
void detect(cv::Mat img_, TargetsInFrame& tgts_);
void getIdsWithLengths(std::vector<int>& ids_, std::vector<double>& lengths_);
private:
void _load();
bool _params_loaded;

79
include/sv_camera.h Normal file
View File

@@ -0,0 +1,79 @@
#ifndef __SV_CAMERA__
#define __SV_CAMERA__
#include "opencv2/opencv.hpp"
namespace sv
{
enum class CameraType : int
{
// 未知相机
NONE = 0X00001000,
// 标准opencv框架下的相机
V4L2CAM = 0X00001001,
WEBCAM = 0X00001002,
// 视频文件
VIDEOFILE = 0X00002001,
// 普通流媒体相机
STREAMING = 0X00004001,
// 普通的MIPI-CSI相机
MIPI = 0X00008001,
// 进行了传输优化适配的相机
G1 = 0X00010001,
Q10 = 0X00010002,
GX40 = 0X00010003,
MC1 = 0X00010004,
// 虚拟的相机设备 主要仿真接入
VIRTUAL = 0X00020001,
};
class Camera
{
private:
void *dev;
public:
// 构建时根据相机类型实例化对应的相机类
// timeOut: 相机连接超时时间;超过该时间没有读取到新的帧,则认为相机失去连接 单位ms
Camera(CameraType type, int timeOut = 500);
// 基本配置 必须调用下述的一个接口后才能open
bool setStream(const std::string &ip, int port);
bool setName(const std::string &name);
bool setIndex(int index);
// 基础功能
bool open(void);
bool read(cv::Mat &image);
bool readNoBlock(cv::Mat &image);
void release(void);
// 属性配置
void setWH(int width, int height);
void setFps(int fps);
void setBrightness(double brightness);
void setContrast(double contrast);
void setSaturation(double saturation);
void setHue(double hue);
void setExposure(double exposure);
// 获取属性
bool isActive(void);
CameraType getType(void);
std::string getName(void);
int getW(void);
int getH(void);
int getExpectFps(void);
double getFps(void);
double getBrightness(void);
double getContrast(void);
double getSaturation(void);
double getHue(void);
double getExposure(void);
~Camera();
};
}
#endif

View File

@@ -25,6 +25,7 @@ public:
double line_location_a2;
bool is_load_parameter;
std::string line_color;
protected:
@@ -39,4 +40,4 @@ protected:
void seg(cv::Mat line_area_, cv::Mat line_area_a1_, cv::Mat line_area_a2_, std::string line_color_, cv::Point &center_, int &area_, cv::Point &center_a1_, cv::Point &center_a2_);
};
}
#endif
#endif

View File

@@ -8,36 +8,33 @@
#include <string>
#include <chrono>
namespace sv
{
namespace sv {
class CommonObjectDetectorCUDAImpl;
class CommonObjectDetectorIntelImpl;
class CommonObjectDetector : public CommonObjectDetectorBase
{
public:
CommonObjectDetector(bool input_4k = false);
CommonObjectDetector(bool input_4k=false);
~CommonObjectDetector();
protected:
bool setupImpl();
void detectImpl(
cv::Mat img_,
std::vector<float> &boxes_x_,
std::vector<float> &boxes_y_,
std::vector<float> &boxes_w_,
std::vector<float> &boxes_h_,
std::vector<int> &boxes_label_,
std::vector<float> &boxes_score_,
std::vector<cv::Mat> &boxes_seg_);
CommonObjectDetectorCUDAImpl *_cuda_impl;
CommonObjectDetectorIntelImpl *_intel_impl;
std::vector<float>& boxes_x_,
std::vector<float>& boxes_y_,
std::vector<float>& boxes_w_,
std::vector<float>& boxes_h_,
std::vector<int>& boxes_label_,
std::vector<float>& boxes_score_,
std::vector<cv::Mat>& boxes_seg_
);
CommonObjectDetectorCUDAImpl* _cuda_impl;
bool _input_4k;
};
}
#endif

View File

@@ -12,7 +12,6 @@
namespace sv {
class LandingMarkerDetectorCUDAImpl;
class LandingMarkerDetectorIntelImpl;
class LandingMarkerDetector : public LandingMarkerDetectorBase
{
@@ -26,8 +25,7 @@ protected:
std::vector<int>& output_labels_
);
LandingMarkerDetectorCUDAImpl *_cuda_impl;
LandingMarkerDetectorIntelImpl *_intel_impl;
LandingMarkerDetectorCUDAImpl* _cuda_impl;
};

View File

@@ -11,34 +11,33 @@
namespace sv
{
class VeriDetectorCUDAImpl;
class VeriDetectorIntelImpl;
class VeriDetectorCUDAImpl;
class VeriDetector : public LandingMarkerDetectorBase
{
public:
VeriDetector();
~VeriDetector();
class VeriDetector : public LandingMarkerDetectorBase
{
public:
VeriDetector();
~VeriDetector();
void detect(cv::Mat img_, const cv::Rect &bounding_box_, sv::Target &tgt);
void detect(cv::Mat img_, const cv::Rect &bounding_box_, sv::Target &tgt);
protected:
void _load();
bool setupImpl();
void roiCNN(
std::vector<cv::Mat> &input_rois_,
std::vector<float> &output_labels_);
void getSubwindow(cv::Mat &dstCrop, cv::Mat &srcImg, int originalSz, int resizeSz);
protected:
void _load();
bool setupImpl();
void roiCNN(
std::vector<cv::Mat> &input_rois_,
std::vector<float> &output_labels_);
void getSubwindow(cv::Mat &dstCrop, cv::Mat &srcImg, int originalSz, int resizeSz);
std::string vehicle_id;
std::string vehicle_id;
// Save the target bounding box for each frame.
std::vector<float> targetSz = {0, 0}; // H and W of bounding box
std::vector<float> targetPos = {0, 0}; // center point of bounding box (x, y)
// Save the target bounding box for each frame.
std::vector<float> targetSz = {0, 0}; // H and W of bounding box
std::vector<float> targetPos = {0, 0}; // center point of bounding box (x, y)
VeriDetectorCUDAImpl *_cuda_impl;
VeriDetectorIntelImpl *_intel_impl;
};
VeriDetectorCUDAImpl *_cuda_impl;
};
}
#endif

View File

@@ -128,7 +128,6 @@ public:
bool getBox(Box& b);
bool getAruco(int& id, std::vector<cv::Point2f> &corners);
bool getAruco(int& id, std::vector<cv::Point2f> &corners, cv::Vec3d &rvecs, cv::Vec3d &tvecs);
bool getEllipse(double& xc_, double& yc_, double& a_, double& b_, double& rad_);
std::string getJsonStr();
@@ -327,66 +326,59 @@ protected:
};
enum class CameraType {NONE, WEBCAM, V4L2CAM, MIPI, RTSP, VIDEO, G1, Q10, GX40};
// enum class CameraType {NONE, WEBCAM, V4L2CAM, G1, Q10, MIPI, GX40};
class CameraBase {
public:
CameraBase(CameraType type=CameraType::NONE, int id=0);
~CameraBase();
void open(CameraType type=CameraType::V4L2CAM, int id=0);
bool read(cv::Mat& image);
void release();
// class CameraBase {
// public:
// CameraBase(CameraType type=CameraType::NONE, int id=0);
// ~CameraBase();
// void open(CameraType type=CameraType::WEBCAM, int id=0);
// bool read(cv::Mat& image);
// void release();
int getW();
int getH();
int getFps();
std::string getIp();
int getPort();
double getBrightness();
double getContrast();
double getSaturation();
double getHue();
double getExposure();
std::string getFourcc();
bool isRunning();
void setFourcc(std::string fourcc);
void setWH(int width, int height);
void setFps(int fps);
void setIp(std::string ip);
void setRtspUrl(std::string rtsp_url);
void setVideoPath(std::string video_path);
void setPort(int port);
void setBrightness(double brightness);
void setContrast(double contrast);
void setSaturation(double saturation);
void setHue(double hue);
void setExposure(double exposure);
protected:
virtual void openImpl();
void _run();
// int getW();
// int getH();
// int getFps();
// std::string getIp();
// int getPort();
// double getBrightness();
// double getContrast();
// double getSaturation();
// double getHue();
// double getExposure();
// bool isRunning();
// void setWH(int width, int height);
// void setFps(int fps);
// void setIp(std::string ip);
// void setPort(int port);
// void setBrightness(double brightness);
// void setContrast(double contrast);
// void setSaturation(double saturation);
// void setHue(double hue);
// void setExposure(double exposure);
// protected:
// virtual void openImpl();
// void _run();
bool _is_running;
bool _is_updated;
std::thread _tt;
cv::VideoCapture _cap;
cv::Mat _frame;
CameraType _type;
int _camera_id;
// bool _is_running;
// bool _is_updated;
// std::thread _tt;
// cv::VideoCapture _cap;
// cv::Mat _frame;
// CameraType _type;
// int _camera_id;
int _width;
int _height;
int _fps;
std::string _ip;
std::string _rtsp_url;
std::string _video_path;
int _port;
double _brightness;
double _contrast;
double _saturation;
double _hue;
double _exposure;
std::string _fourcc;
};
// int _width;
// int _height;
// int _fps;
// std::string _ip;
// int _port;
// double _brightness;
// double _contrast;
// double _saturation;
// double _hue;
// double _exposure;
// };
void drawTargetsInFrame(
@@ -401,16 +393,6 @@ void drawTargetsInFrame(
bool with_aruco=false,
bool with_yaw=false
);
cv::Mat drawTargetsInFrame(
const cv::Mat img_,
const TargetsInFrame& tgts_,
const double scale,
bool with_all=true,
bool with_category=false,
bool with_tid=false,
bool with_seg=false,
bool with_box=false
);
std::string get_home();
bool is_file_exist(std::string& fn);
void list_dir(std::string dir, std::vector<std::string>& files, std::string suffixs="", bool r=false);

View File

@@ -1,3 +1,4 @@
#if 0
#ifndef __SV_VIDEO_INPUT__
#define __SV_VIDEO_INPUT__
@@ -25,3 +26,4 @@ protected:
}
#endif
#endif

View File

@@ -39,6 +39,8 @@ the use of this software, even if advised of the possibility of such damage.
#include <sv_world.h>
#include "aruco_samples_utility.hpp"
#include "sv_camera.h"
using namespace std;
using namespace cv;
@@ -146,10 +148,14 @@ int main(int argc, char *argv[]) {
}
// VideoCapture inputVideo;
sv::Camera inputVideo;
sv::Camera inputVideo(c_type);
inputVideo.setIndex(camId);
inputVideo.setStream("192.168.144.64",554);
inputVideo.setWH(imW, imH);
inputVideo.setFps(fps);
inputVideo.open(c_type, camId);
inputVideo.open();
int waitTime = 10;

View File

@@ -97,8 +97,7 @@ int main(int argc, char *argv[]) {
if (landingPadUnit > 0) {
Mat markerImgBIG = Mat::ones(landingPadUnit * 62, landingPadUnit * 62, CV_8UC1) * 255;
// markerId = 0;
markerId --;
markerId = 0;
markerSize = landingPadUnit * 4;
borderSize = landingPadUnit;
int newSize = markerSize + borderSize * 2;
@@ -223,7 +222,7 @@ int main(int argc, char *argv[]) {
markerImg = create_marker_with_borders(dictionary, markerId, markerSize, borderBits, borderSize);
markerImg.copyTo(markerImgBIG(Rect(landingPadUnit * 10, landingPadUnit * 28, newSize, newSize)));
// markerId = 90;
markerId = 90;
markerSize = landingPadUnit * 4 * 4;
borderSize = landingPadUnit * 4;
newSize = markerSize + borderSize * 2;

View File

@@ -2,6 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
@@ -9,14 +10,15 @@ int main(int argc, char *argv[]) {
// 实例化Aruco检测器类
sv::ArucoDetector ad;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
ad.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
ad.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
ad.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(ad.image_width, ad.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;

View File

@@ -2,15 +2,17 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
int main(int argc, char *argv[]) {
// 打开摄像头
sv::Camera cap;
cap.setWH(1280, 720);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
// cap.setWH(640, 480);
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
while (1)

View File

@@ -2,6 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
using namespace sv;
@@ -11,14 +12,14 @@ int main(int argc, char *argv[])
// 实例化 color line detection 检测器类
sv::ColorLineDetector cld;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
cld.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
cld.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
cld.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(cld.image_width, cld.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;

View File

@@ -2,6 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
@@ -9,14 +10,14 @@ int main(int argc, char *argv[]) {
// 实例化 通用目标 检测器类
sv::CommonObjectDetector cod;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
cod.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
cod.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
cod.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(cod.image_width, cod.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;

View File

@@ -2,6 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
@@ -40,20 +41,19 @@ int main(int argc, char *argv[]) {
// 实例化 框选目标跟踪类
sv::SingleObjectTracker sot;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
sot.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
sot.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
sot.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
sv::CommonObjectDetector cod;
cod.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
cod.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
cod.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(cod.image_width, cod.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;

View File

@@ -2,6 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
@@ -9,14 +10,15 @@ int main(int argc, char *argv[]) {
// 实例化 椭圆 检测器类
sv::EllipseDetector ed;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
ed.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
ed.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
ed.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(ed.image_width, ed.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;

View File

@@ -3,6 +3,7 @@
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include <map>
#include "sv_camera.h"
// 定义窗口名称
static const std::string RGB_WINDOW = "Image window";
@@ -34,36 +35,44 @@ void gimbalNoTrack(void)
int main(int argc, char *argv[])
{
// 实例化 框选目标跟踪类
sv::SingleObjectTracker sot;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
sot.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_1280x720.yaml");
sv::CommonObjectDetector cod;
cod.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_1280x720.yaml");
// 实例化吊舱
gimbal = new sv::Gimbal(sv::GimbalType::G1, sv::GimbalLink::SERIAL);
// 使用 /dev/ttyUSB0 作为控制串口
gimbal->setSerialPort("/dev/ttyUSB0");
// 以GimableCallback作为状态回调函数启用吊舱控制
gimbal->open(GimableCallback);
// 定义相机
sv::Camera cap;
// 设置相机流媒体地址为 192.168.2.64
cap.setIp("192.168.2.64");
// 设置获取画面分辨率为720P
cap.setWH(1280, 720);
// 设置视频帧率为30帧
// 打开摄像头
sv::Camera cap(sv::CameraType::G1);
cap.setStream("192.168.2.64",554);
cap.setWH(cod.image_width, cod.image_height);
cap.setFps(30);
// 开启相机
cap.open(sv::CameraType::G1);
cap.open(); // CameraID 0
// // 定义相机
// sv::Camera cap;
// // 设置相机流媒体地址为 192.168.2.64
// cap.setIp("192.168.2.64");
// // 设置获取画面分辨率为720P
// cap.setWH(1280, 720);
// // 设置视频帧率为30帧
// cap.setFps(30);
// // 开启相机
// cap.open(sv::CameraType::G1);
// 定义一个新的窗口,可在上面进行框选操作
cv::namedWindow(RGB_WINDOW);
// 设置窗口操作回调函数,该函数实现整个框选逻辑
cv::setMouseCallback(RGB_WINDOW, onMouse, 0);
// 实例化 框选目标跟踪类
sv::SingleObjectTracker sot;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
sot.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
sot.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
sv::CommonObjectDetector cod;
cod.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
cod.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
@@ -258,4 +267,4 @@ void GimableCallback(double &frame_ang_r, double &frame_ang_p, double &frame_ang
count = 0;
}
count++;
}
}

View File

@@ -3,6 +3,7 @@
// 包含SpireCV SDK头文件
#include <sv_world.h>
// #include "gimbal_tools.hpp"
#include "sv_camera.h"
using namespace std;
@@ -33,33 +34,40 @@ void gimbalNoTrack(void)
}
int main(int argc, char *argv[])
{
{
// 实例化 圆形降落标志 检测器类
sv::LandingMarkerDetector lmd;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
lmd.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_1280x720.yaml");
// 实例化吊舱
gimbal = new sv::Gimbal(sv::GimbalType::G1, sv::GimbalLink::SERIAL);
// 使用 /dev/ttyUSB0 作为控制串口
gimbal->setSerialPort("/dev/ttyUSB0");
// 以GimableCallback作为状态回调函数启用吊舱控制
gimbal->open(GimableCallback);
// 定义相机
sv::Camera cap;
// 设置相机流媒体地址为 192.168.2.64
cap.setIp("192.168.2.64");
// 设置获取画面分辨率为720P
cap.setWH(1280, 720);
// 设置视频帧率为30帧
// 打开摄像头
sv::Camera cap(sv::CameraType::G1);
cap.setStream("192.168.2.64", 554);
cap.setWH(lmd.image_width, lmd.image_height);
cap.setFps(30);
// 开启相机
cap.open(sv::CameraType::G1);
cap.open(); // CameraID 0
// // 定义相机
// sv::Camera cap;
// // 设置相机流媒体地址为 192.168.2.64
// cap.setIp("192.168.2.64");
// // 设置获取画面分辨率为720P
// cap.setWH(1280, 720);
// // 设置视频帧率为30帧
// cap.setFps(30);
// // 开启相机
// cap.open(sv::CameraType::G1);
// 定义一个窗口 才可以在上面操作
cv::namedWindow(RGB_WINDOW);
// 设置窗口操作回调函数,该函数实现吊舱控制
cv::setMouseCallback(RGB_WINDOW, onMouse, 0);
// 实例化 圆形降落标志 检测器类
sv::LandingMarkerDetector lmd;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
lmd.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
lmd.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
@@ -145,4 +153,4 @@ void GimableCallback(double &frame_ang_r, double &frame_ang_p, double &frame_ang
count = 0;
}
count++;
}
}

View File

@@ -2,6 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
@@ -42,33 +43,41 @@ static const std::string RGB_WINDOW = "Image window";
void onMouse(int event, int x, int y, int, void *);
int main(int argc, char *argv[])
{
{
// 实例化Aruco检测器类
sv::ArucoDetector ad;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
ad.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_1280x720.yaml");
// 实例化吊舱
gimbal = new sv::Gimbal(sv::GimbalType::G1, sv::GimbalLink::SERIAL);
// 使用 /dev/ttyUSB0 作为控制串口
gimbal->setSerialPort("/dev/ttyUSB0");
// 以gimableCallback作为状态回调函数启用吊舱控制
gimbal->open(gimableCallback);
// 定义相机
sv::Camera cap;
// 设置相机流媒体地址为 192.168.2.64
cap.setIp("192.168.2.64");
// 设置获取画面分辨率为720P
cap.setWH(1280, 720);
// 设置视频帧率为30帧
// 打开摄像头
sv::Camera cap(sv::CameraType::G1);
cap.setStream("192.168.2.64",554);
cap.setWH(ad.image_width, ad.image_height);
cap.setFps(30);
// 开启相机
cap.open(sv::CameraType::G1);
cap.open(); // CameraID 0
// // 定义相机
// sv::Camera cap;
// // 设置相机流媒体地址为 192.168.2.64
// cap.setIp("192.168.2.64");
// // 设置获取画面分辨率为720P
// cap.setWH(1280, 720);
// // 设置视频帧率为30帧
// cap.setFps(30);
// // 开启相机
// cap.open(sv::CameraType::G1);
// 定义一个窗口 才可以在上面操作
cv::namedWindow(RGB_WINDOW);
// 设置窗口操作回调函数,该函数实现吊舱控制
cv::setMouseCallback(RGB_WINDOW, onMouse, 0);
// 实例化Aruco检测器类
sv::ArucoDetector ad;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
ad.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
ad.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
sv::UDPServer udp;
// 实例化OpenCV的Mat类用于内存单帧图像

View File

@@ -2,21 +2,22 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
int main(int argc, char *argv[]) {
// 实例化 圆形降落标志 检测器类
sv::LandingMarkerDetector lmd;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
lmd.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
lmd.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
lmd.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
// 打开摄像头
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(lmd.image_width, lmd.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;

View File

@@ -2,6 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
@@ -9,19 +10,19 @@ int main(int argc, char *argv[]) {
// 实例化
sv::CommonObjectDetector cod;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
cod.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
cod.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
cod.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
sv::MultipleObjectTracker mot;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
mot.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
mot.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
mot.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
mot.init(&cod);
// 打开摄像头
sv::Camera cap;
cap.setWH(mot.image_width, mot.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// 打开摄像头
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(cod.image_width, cod.image_height);
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;

View File

@@ -2,7 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
// 定义窗口名称
@@ -28,15 +28,17 @@ int main(int argc, char *argv[]) {
// 实例化 框选目标跟踪类
sv::SingleObjectTracker sot;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
sot.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// sot.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_1280x720.yaml");
// sot.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_1920x1080.yaml");
sot.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
sot.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
// 打开摄像头
sv::Camera cap;
// 打开摄像头
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(sot.image_width, sot.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// cv::VideoCapture cap("/home/amov/SpireCV/test/tracking_1280x720.mp4");
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;

View File

@@ -2,20 +2,21 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
int main(int argc, char *argv[]) {
// 实例化Aruco检测器类
sv::ArucoDetector ad;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
ad.loadCameraParams("/home/amov/SpireCV/calib_webcam_1280x720.yaml");
ad.loadCameraParams("/home/amov/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
// 打开摄像头
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(ad.image_width, ad.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
sv::UDPServer udp;
// 实例化OpenCV的Mat类用于内存单帧图像

View File

@@ -2,7 +2,7 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
struct node
@@ -20,18 +20,17 @@ int main(int argc, char *argv[])
// 实例化 框选目标跟踪类
sv::VeriDetector veri;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
veri.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
veri.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
veri.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
sv::CommonObjectDetector cod;
cod.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
cod.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
cod.loadCameraParams(sv::get_home() + "/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
// 打开摄像头
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(cod.image_width, cod.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;

View File

@@ -2,21 +2,22 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
int main(int argc, char *argv[]) {
// 实例化 通用目标 检测器类
sv::CommonObjectDetector cod;
// 手动导入相机参数如果使用Amov的G1等吊舱或相机则可以忽略该步骤将自动下载相机参数文件
cod.loadCameraParams(sv::get_home() + "/SpireCV/confs/calib_webcam_1280x720.yaml");
cod.loadAlgorithmParams(sv::get_home() + "/SpireCV/confs/sv_algorithm_params.json");
cod.loadCameraParams("/home/amov/SpireCV/calib_webcam_640x480.yaml");
// 打开摄像头
sv::Camera cap;
// 打开摄像头
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(cod.image_width, cod.image_height);
cap.setFps(30);
cap.open(sv::CameraType::V4L2CAM, 0); // CameraID 0
// cap.setFps(30);
cap.open(); // CameraID 0
// 实例化OpenCV的Mat类用于内存单帧图像
cv::Mat img;
int frame_id = 0;
@@ -24,7 +25,7 @@ int main(int argc, char *argv[]) {
// 实例化视频保存类
sv::VideoWriter vw;
// 设置保存路径"/home/amov/Videos"保存图像尺寸640480帧频25Hz同步保存检测结果.svj
vw.setup(sv::get_home() + "/Videos", cv::Size(cod.image_width, cod.image_height), 25, true);
vw.setup("/home/amov/Videos", cv::Size(640, 480), 25, true);
while (1)
{
@@ -32,7 +33,7 @@ int main(int argc, char *argv[]) {
sv::TargetsInFrame tgts(frame_id++);
// 读取一帧图像到img
cap.read(img);
cv::resize(img, img, cv::Size(cod.image_width, cod.image_height));
cv::resize(img, img, cv::Size(640, 480));
// 执行通用目标检测
cod.detect(img, tgts);

View File

@@ -2,15 +2,17 @@
#include <string>
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include "sv_camera.h"
using namespace std;
int main(int argc, char *argv[]) {
// 打开摄像头
sv::Camera cap;
// cap.setWH(1280, 720);
// cap.setFps(30);
cap.open(sv::CameraType::WEBCAM, 0); // CameraID 0
// 打开摄像头
sv::Camera cap(sv::CameraType::WEBCAM);
cap.setIndex(0);
cap.setWH(1280, 720);
cap.setFps(30);
cap.open(); // CameraID 0
// 实例化视频推流类sv::VideoStreamer
sv::VideoStreamer streamer;

View File

@@ -3,6 +3,7 @@
// 包含SpireCV SDK头文件
#include <sv_world.h>
#include <chrono>
#include "sv_camera.h"
// yaw roll pitch
double gimbalEulerAngle[3];
@@ -143,14 +144,20 @@ int main(int argc, char *argv[])
std::cout << " pass... " << std::endl;
std::cout << " start image test " << std::endl;
sv::Camera cap;
cap.setIp(argv[2]);
// 打开摄像头
sv::Camera cap(sv::CameraType::G1);
cap.setStream(argv[2], 554);
cap.setWH(1280, 720);
cap.setFps(30);
cap.open(); // CameraID 0
cap.open(sv::CameraType::G1);
// sv::Camera cap;
// cap.setIp(argv[2]);
// cap.setWH(1280, 720);
// cap.setFps(30);
// cap.open(sv::CameraType::G1);
if (!cap.isRunning())
if (!cap.isActive())
{
std::cout << " gimbal image error , failed !!!!!" << std::endl;
return -1;

0
scripts/common/configs-downloading.sh Executable file → Normal file
View File

0
scripts/common/download_test_videos.sh Executable file → Normal file
View File

1
scripts/common/ffmpeg425-install.sh Executable file → Normal file
View File

@@ -17,7 +17,6 @@ cd nv-codec-headers
git checkout n11.1.5.0
sudo make install
cd ..
sudo rm -r nv-codec-headers
wget https://ffmpeg.org/releases/ffmpeg-4.2.5.tar.bz2
tar -xjf ffmpeg-4.2.5.tar.bz2

0
scripts/common/gst-install-orin.sh Executable file → Normal file
View File

0
scripts/common/gst-install.sh Executable file → Normal file
View File

0
scripts/common/models-converting.sh Executable file → Normal file
View File

28
scripts/common/models-downloading.sh Executable file → Normal file
View File

@@ -3,6 +3,12 @@
root_dir=${HOME}"/SpireCV/models"
root_server="https://download.amovlab.com/model"
sv_params1=${HOME}"/SpireCV/sv_algorithm_params.json"
sv_params2=${HOME}"/SpireCV/sv_algorithm_params_coco_640.json"
sv_params3=${HOME}"/SpireCV/sv_algorithm_params_coco_1280.json"
camera_params1=${HOME}"/SpireCV/calib_webcam_640x480.yaml"
camera_params2=${HOME}"/SpireCV/calib_webcam_1280x720.yaml"
coco_model1="COCO-yolov5s.wts"
coco_model2="COCO-yolov5s6.wts"
coco_model3="COCO-yolov5s-seg.wts"
@@ -40,6 +46,28 @@ if [ ! -d ${root_dir} ]; then
mkdir -p ${root_dir}
fi
if [ ! -f ${sv_params1} ]; then
echo -e "\033[32m[INFO]: ${sv_params1} not exist, downloading ... \033[0m"
wget -O ${sv_params1} ${root_server}/install/a-params/sv_algorithm_params.json
fi
if [ ! -f ${sv_params2} ]; then
echo -e "\033[32m[INFO]: ${sv_params2} not exist, downloading ... \033[0m"
wget -O ${sv_params2} ${root_server}/install/a-params/sv_algorithm_params_coco_640.json
fi
if [ ! -f ${sv_params3} ]; then
echo -e "\033[32m[INFO]: ${sv_params3} not exist, downloading ... \033[0m"
wget -O ${sv_params3} ${root_server}/install/a-params/sv_algorithm_params_coco_1280.json
fi
if [ ! -f ${camera_params1} ]; then
echo -e "\033[32m[INFO]: ${camera_params1} not exist, downloading ... \033[0m"
wget -O ${camera_params1} ${root_server}/install/c-params/calib_webcam_640x480.yaml
fi
if [ ! -f ${camera_params2} ]; then
echo -e "\033[32m[INFO]: ${camera_params2} not exist, downloading ... \033[0m"
wget -O ${camera_params2} ${root_server}/install/c-params/calib_webcam_1280x720.yaml
fi
if [ ! -f ${coco_model1_fn} ]; then
echo -e "\033[32m[INFO]: ${coco_model1_fn} not exist, downloading ... \033[0m"
wget -O ${coco_model1_fn} ${root_server}/install/${coco_model1}

0
scripts/common/opencv470-install.sh Executable file → Normal file
View File

View File

@@ -1,39 +0,0 @@
#!/bin/bash -e
root_dir=${HOME}"/SpireCV/models"
root_server="https://download.amovlab.com/model"
sv_params1=${HOME}"/SpireCV/sv_algorithm_params.json"
sv_params2=${HOME}"/SpireCV/sv_algorithm_params_coco_640.json"
sv_params3=${HOME}"/SpireCV/sv_algorithm_params_coco_1280.json"
camera_params1=${HOME}"/SpireCV/calib_webcam_640x480.yaml"
camera_params2=${HOME}"/SpireCV/calib_webcam_1280x720.yaml"
if [ ! -d ${root_dir} ]; then
echo -e "\033[32m[INFO]: ${root_dir} not exist, creating it ... \033[0m"
mkdir -p ${root_dir}
fi
if [ ! -f ${sv_params1} ]; then
echo -e "\033[32m[INFO]: ${sv_params1} not exist, downloading ... \033[0m"
wget -O ${sv_params1} ${root_server}/install/a-params/sv_algorithm_params.json
fi
if [ ! -f ${sv_params2} ]; then
echo -e "\033[32m[INFO]: ${sv_params2} not exist, downloading ... \033[0m"
wget -O ${sv_params2} ${root_server}/install/a-params/sv_algorithm_params_coco_640.json
fi
if [ ! -f ${sv_params3} ]; then
echo -e "\033[32m[INFO]: ${sv_params3} not exist, downloading ... \033[0m"
wget -O ${sv_params3} ${root_server}/install/a-params/sv_algorithm_params_coco_1280.json
fi
if [ ! -f ${camera_params1} ]; then
echo -e "\033[32m[INFO]: ${camera_params1} not exist, downloading ... \033[0m"
wget -O ${camera_params1} ${root_server}/install/c-params/calib_webcam_640x480.yaml
fi
if [ ! -f ${camera_params2} ]; then
echo -e "\033[32m[INFO]: ${camera_params2} not exist, downloading ... \033[0m"
wget -O ${camera_params2} ${root_server}/install/c-params/calib_webcam_1280x720.yaml
fi

View File

@@ -1,24 +0,0 @@
#!/bin/sh
sudo apt install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt install -y libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base
sudo apt install -y gstreamer1.0-plugins-good gstreamer1.0-plugins-bad
sudo apt install -y gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc
sudo apt install -y gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa
sudo apt install -y gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5
sudo apt install -y gstreamer1.0-pulseaudio
sudo apt install -y gtk-doc-tools
sudo apt install -y libeigen3-dev libfmt-dev v4l-utils
sudo apt -y install autotools-dev automake m4 perl
sudo apt -y install libtool
autoreconf -ivf
git clone https://gitee.com/jario-jin/gst-rtsp-server-b18.git
cd gst-rtsp-server-b18
./autogen.sh
make
sudo make install
cd ..
sudo rm -r gst-rtsp-server-b18

View File

@@ -1,20 +0,0 @@
#!/bin/sh
sudo apt install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt install -y libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base
sudo apt install -y gstreamer1.0-plugins-good gstreamer1.0-plugins-bad
sudo apt install -y gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc
sudo apt install -y gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa
sudo apt install -y gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5
sudo apt install -y gstreamer1.0-pulseaudio
sudo apt install -y gtk-doc-tools
sudo apt install -y libeigen3-dev libfmt-dev v4l-utils
git clone https://gitee.com/jario-jin/gst-rtsp-server-b18.git
cd gst-rtsp-server-b18
./autogen.sh
make
sudo make install
cd ..
sudo rm -r gst-rtsp-server-b18

View File

@@ -1,70 +0,0 @@
#!/bin/sh
wget https://download.amovlab.com/model/deps/opencv-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_contrib-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_cache_x86-4.7.0.zip
current_dir=$(pwd)
package_dir="."
mkdir ~/opencv_build
if [ ! -d ""$package_dir"" ];then
echo "\033[31m[ERROR]: $package_dir not exist!: \033[0m"
exit 1
fi
# sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
# sudo add-apt-repository "deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe"
sudo apt update
sudo apt install -y build-essential
sudo apt install -y cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32
sudo apt update
sudo apt install -y libjasper1 libjasper-dev
sudo apt install -y python3-dev python3-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev
sudo apt install -y libdc1394-22-dev
sudo apt install -y libcurl4 build-essential pkg-config cmake libopenblas-dev libeigen3-dev \
libtbb-dev libavcodec-dev libavformat-dev libgstreamer-plugins-base1.0-dev \
libgstreamer1.0-dev libswscale-dev libgtk-3-dev libpng-dev libjpeg-dev \
libcanberra-gtk-module libcanberra-gtk3-module
echo "\033[32m[INFO]:\033[0m unzip opencv-4.7.0.zip ..."
unzip -q -o $package_dir/opencv-4.7.0.zip -d ~/opencv_build
echo "\033[32m[INFO]:\033[0m unzip opencv_contrib-4.7.0.zip ..."
unzip -q -o $package_dir/opencv_contrib-4.7.0.zip -d ~/opencv_build
echo "\033[32m[INFO]:\033[0m unzip opencv_cache_x86-4.7.0.zip ..."
unzip -q -o $package_dir/opencv_cache_x86-4.7.0.zip -d ~/opencv_build
sudo rm opencv-4.7.0.zip
sudo rm opencv_contrib-4.7.0.zip
sudo rm opencv_cache_x86-4.7.0.zip
cd ~/opencv_build/opencv-4.7.0
mkdir .cache
cp -r ~/opencv_build/opencv_cache_x86-4.7.0/* ~/opencv_build/opencv-4.7.0/.cache/
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release \
-D WITH_CUDA=OFF \
-D OPENCV_ENABLE_NONFREE=ON \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.7.0/modules ..
make -j2
sudo make install
cd
sudo rm -r ~/opencv_build
cd ${current_dir}

3
scripts/jetson/opencv470-jetpack511-cuda-install.sh Executable file → Normal file
View File

@@ -5,7 +5,7 @@ wget https://download.amovlab.com/model/deps/opencv-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_contrib-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_cache-4.7.0.zip
current_dir=$(pwd)
package_dir="."
mkdir ~/opencv_build
@@ -52,4 +52,3 @@ sudo make install
cd
sudo rm -r ~/opencv_build
cd ${current_dir}

3
scripts/jetson/opencv470-jetpack511-install.sh Executable file → Normal file
View File

@@ -5,7 +5,7 @@ wget https://download.amovlab.com/model/deps/opencv-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_contrib-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_cache-4.7.0.zip
current_dir=$(pwd)
package_dir="."
mkdir ~/opencv_build
@@ -52,4 +52,3 @@ sudo make install
cd
sudo rm -r ~/opencv_build
cd ${current_dir}

View File

@@ -1,39 +0,0 @@
#!/bin/bash -e
root_dir=${HOME}"/SpireCV/models"
root_server="https://download.amovlab.com/model"
sv_params1=${HOME}"/SpireCV/sv_algorithm_params.json"
sv_params2=${HOME}"/SpireCV/sv_algorithm_params_coco_640.json"
sv_params3=${HOME}"/SpireCV/sv_algorithm_params_coco_1280.json"
camera_params1=${HOME}"/SpireCV/calib_webcam_640x480.yaml"
camera_params2=${HOME}"/SpireCV/calib_webcam_1280x720.yaml"
if [ ! -d ${root_dir} ]; then
echo -e "\033[32m[INFO]: ${root_dir} not exist, creating it ... \033[0m"
mkdir -p ${root_dir}
fi
if [ ! -f ${sv_params1} ]; then
echo -e "\033[32m[INFO]: ${sv_params1} not exist, downloading ... \033[0m"
wget -O ${sv_params1} ${root_server}/install/a-params/sv_algorithm_params.json
fi
if [ ! -f ${sv_params2} ]; then
echo -e "\033[32m[INFO]: ${sv_params2} not exist, downloading ... \033[0m"
wget -O ${sv_params2} ${root_server}/install/a-params/sv_algorithm_params_coco_640.json
fi
if [ ! -f ${sv_params3} ]; then
echo -e "\033[32m[INFO]: ${sv_params3} not exist, downloading ... \033[0m"
wget -O ${sv_params3} ${root_server}/install/a-params/sv_algorithm_params_coco_1280.json
fi
if [ ! -f ${camera_params1} ]; then
echo -e "\033[32m[INFO]: ${camera_params1} not exist, downloading ... \033[0m"
wget -O ${camera_params1} ${root_server}/install/c-params/calib_webcam_640x480.yaml
fi
if [ ! -f ${camera_params2} ]; then
echo -e "\033[32m[INFO]: ${camera_params2} not exist, downloading ... \033[0m"
wget -O ${camera_params2} ${root_server}/install/c-params/calib_webcam_1280x720.yaml
fi

View File

@@ -1,66 +0,0 @@
#!/bin/sh
sudo apt install -y \
build-essential yasm cmake libtool libc6 libc6-dev unzip wget libeigen3-dev libfmt-dev \
libnuma1 libnuma-dev libx264-dev libx265-dev libfaac-dev libssl-dev v4l-utils
current_dir=$(pwd)
root_dir=${HOME}"/SpireCV"
if [ ! -d ${root_dir} ]; then
echo -e "\033[32m[INFO]: ${root_dir} not exist, creating it ... \033[0m"
mkdir -p ${root_dir}
fi
cd ${root_dir}
git clone https://gitee.com/jario-jin/nv-codec-headers.git
cd nv-codec-headers
git checkout n11.1.5.0
sudo make install
cd ..
sudo rm -r nv-codec-headers
wget https://ffmpeg.org/releases/ffmpeg-4.2.5.tar.bz2
tar -xjf ffmpeg-4.2.5.tar.bz2
cd ffmpeg-4.2.5
export PATH=$PATH:/usr/local/cuda/bin
sed -i 's#_30#_75#' configure; sed -i 's#_30#_75#' configure
./configure \
--enable-nonfree \
--enable-gpl \
--enable-shared \
--enable-ffmpeg \
--enable-ffplay \
--enable-ffprobe \
--enable-libx264 \
--enable-libx265 \
--enable-cuda-nvcc \
--enable-nvenc \
--enable-cuda \
--enable-cuvid \
--enable-libnpp \
--extra-libs="-lpthread -lm" \
--extra-cflags=-I/usr/local/cuda/include \
--extra-ldflags=-L/usr/local/cuda/lib64
make -j8
sudo make install
cd ..
git clone https://gitee.com/jario-jin/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
mkdir build
cd build
cmake ..
make -j4
cd ..
cd ..
mkdir ZLM
cd ZLM
cp ../ZLMediaKit/release/linux/Debug/MediaServer .
cp ../ZLMediaKit/release/linux/Debug/config.ini .
cd ..
cd ${current_dir}

View File

@@ -1,95 +0,0 @@
#!/bin/sh
echo "\033[32m[INFO]:\033[0m Please enter the folder path of the installation package: "
# package_dir="/home/jario/Downloads/nv"
wget https://download.amovlab.com/model/install/x86-nvidia/cuda-repo-ubuntu1804-11-1-local_11.1.1-455.32.00-1_amd64.deb
wget https://download.amovlab.com/model/install/x86-nvidia/cudnn-11.3-linux-x64-v8.2.1.32.tgz
wget https://download.amovlab.com/model/install/x86-nvidia/nv-tensorrt-repo-ubuntu1804-cuda11.3-trt8.0.1.6-ga-20210626_1-1_amd64.deb
wget https://download.amovlab.com/model/install/x86-nvidia/cuda-ubuntu1804.pin
package_dir="."
cuda_fn=$package_dir"/cuda-repo-ubuntu1804-11-1-local_11.1.1-455.32.00-1_amd64.deb"
cudnn_fn=$package_dir"/cudnn-11.3-linux-x64-v8.2.1.32.tgz"
tensorrt_fn=$package_dir"/nv-tensorrt-repo-ubuntu1804-cuda11.3-trt8.0.1.6-ga-20210626_1-1_amd64.deb"
tmp_dir="/tmp"
echo "\033[32m[INFO]: CUDA_PKG: \033[0m"$cuda_fn
echo "\033[32m[INFO]: CUDNN_PKG: \033[0m"$cudnn_fn
echo "\033[32m[INFO]: TENSORRT_PKG: \033[0m"$tensorrt_fn
# 所有文件都存在时,才会继续执行脚本
if [ ! -f "$cuda_fn" ]; then
echo "\033[31m[ERROR]: CUDA_PKG not exist!: \033[0m"
exit 1
fi
if [ ! -f "$cudnn_fn" ]; then
echo "\033[31m[ERROR]: CUDNN_PKG not exist!: \033[0m"
exit 1
fi
if [ ! -f "$tensorrt_fn" ]; then
echo "\033[31m[ERROR]: TENSORRT_PKG not exist!: \033[0m"
exit 1
fi
# 删除显卡驱动
# sudo apt-get remove nvidia-*
# 安装显卡驱动
# echo "\033[32m[INFO]: Nvidia Driver installing ...\033[0m"
# ubuntu-drivers devices
# sudo ubuntu-drivers autoinstall
# 删除已安装CUDA
# --purge选项会将配置文件、数据库等删除
# sudo apt-get autoremove --purge cuda
# 查看安装了哪些cuda相关的库可以用以下指令
# sudo dpkg -l |grep cuda
# sudo dpkg -P cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01
# sudo dpkg -P cuda-repo-ubuntu1804-11-1-local
# sudo dpkg -P nv-tensorrt-repo-ubuntu1804-cuda10.2-trt8.0.1.6-ga-20210626
# 这个key值是官网文档查到的当然通过apt-key list也能查看
# sudo apt-key list
# sudo apt-key del 7fa2af80
# 安装CUDA
echo "\033[32m[INFO]: CUDA installing ...\033[0m"
# wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo cp $package_dir/cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo dpkg -i $cuda_fn
sudo apt-key add /var/cuda-repo-ubuntu1804-11-1-local/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda
# 安装CUDNN
echo "\033[32m[INFO]: CUDNN installing ...\033[0m"
tar zxvf $cudnn_fn -C $tmp_dir
sudo cp $tmp_dir/cuda/include/cudnn* /usr/local/cuda/include/
sudo cp $tmp_dir/cuda/lib64/libcudnn* /usr/local/cuda/lib64/
sudo chmod a+r /usr/local/cuda/include/cudnn* /usr/local/cuda/lib64/libcudnn*
sudo ln -sf /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8.2.1 /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8
sudo ln -sf /usr/local/cuda/targets/x86_64-linux/lib/libcudnn.so.8.2.1 /usr/local/cuda/targets/x86_64-linux/lib/libcudnn.so.8
sudo ln -sf /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_ops_train.so.8.2.1 /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_ops_train.so.8
sudo ln -sf /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.2.1 /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_adv_train.so.8
sudo ln -sf /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8.2.1 /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8
sudo ln -sf /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8.2.1 /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8
sudo ln -sf /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8.2.1 /usr/local/cuda/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8
# 安装TensorRT
sudo dpkg -i $tensorrt_fn
sudo apt-key add /var/nv-tensorrt-repo-cuda11.3-trt8.0.1.6-ga-20210626/7fa2af80.pub
sudo apt-get update
sudo apt-get install tensorrt -y
sudo apt-get install python3-libnvinfer-dev -y
sudo rm $cuda_fn
sudo rm $cudnn_fn
sudo rm $tensorrt_fn
sudo rm cuda-ubuntu1804.pin

View File

@@ -5,7 +5,7 @@ wget https://download.amovlab.com/model/deps/opencv-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_contrib-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_cache_x86-4.7.0.zip
current_dir=$(pwd)
package_dir="."
mkdir ~/opencv_build
@@ -67,4 +67,3 @@ sudo make install
cd
sudo rm -r ~/opencv_build
cd ${current_dir}

View File

@@ -5,7 +5,7 @@ wget https://download.amovlab.com/model/deps/opencv-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_contrib-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_cache_x86-4.7.0.zip
current_dir=$(pwd)
package_dir="."
mkdir ~/opencv_build
@@ -67,4 +67,3 @@ sudo make install
cd
sudo rm -r ~/opencv_build
cd ${current_dir}

View File

@@ -1,39 +0,0 @@
#!/bin/bash -e
root_dir=${HOME}"/SpireCV/models"
root_server="https://download.amovlab.com/model"
sv_params1=${HOME}"/SpireCV/sv_algorithm_params.json"
sv_params2=${HOME}"/SpireCV/sv_algorithm_params_coco_640.json"
sv_params3=${HOME}"/SpireCV/sv_algorithm_params_coco_1280.json"
camera_params1=${HOME}"/SpireCV/calib_webcam_640x480.yaml"
camera_params2=${HOME}"/SpireCV/calib_webcam_1280x720.yaml"
if [ ! -d ${root_dir} ]; then
echo -e "\033[32m[INFO]: ${root_dir} not exist, creating it ... \033[0m"
mkdir -p ${root_dir}
fi
if [ ! -f ${sv_params1} ]; then
echo -e "\033[32m[INFO]: ${sv_params1} not exist, downloading ... \033[0m"
wget -O ${sv_params1} ${root_server}/install/a-params/sv_algorithm_params.json
fi
if [ ! -f ${sv_params2} ]; then
echo -e "\033[32m[INFO]: ${sv_params2} not exist, downloading ... \033[0m"
wget -O ${sv_params2} ${root_server}/install/a-params/sv_algorithm_params_coco_640.json
fi
if [ ! -f ${sv_params3} ]; then
echo -e "\033[32m[INFO]: ${sv_params3} not exist, downloading ... \033[0m"
wget -O ${sv_params3} ${root_server}/install/a-params/sv_algorithm_params_coco_1280.json
fi
if [ ! -f ${camera_params1} ]; then
echo -e "\033[32m[INFO]: ${camera_params1} not exist, downloading ... \033[0m"
wget -O ${camera_params1} ${root_server}/install/c-params/calib_webcam_640x480.yaml
fi
if [ ! -f ${camera_params2} ]; then
echo -e "\033[32m[INFO]: ${camera_params2} not exist, downloading ... \033[0m"
wget -O ${camera_params2} ${root_server}/install/c-params/calib_webcam_1280x720.yaml
fi

View File

@@ -1,26 +0,0 @@
#!/bin/sh
sudo apt install -y v4l-utils
wget https://ffmpeg.org/releases/ffmpeg-4.2.5.tar.bz2
tar -xjf ffmpeg-4.2.5.tar.bz2
cd ffmpeg-4.2.5
./configure \
--arch=x86_64 \
--disable-x86asm \
--enable-vaapi \
--enable-libmfx \
--enable-nonfree \
--enable-shared \
--enable-ffmpeg \
--enable-ffplay \
--enable-ffprobe \
--enable-libx264 \
--enable-libx265 \
--enable-gpl
make -j8
sudo make install
cd ..
sudo rm -r ffmpeg-4.2.5
sudo rm ffmpeg-4.2.5.tar.bz2

View File

@@ -1,6 +0,0 @@
#!/bin/sh
sudo apt-get install -y libmfx1 libmfx-tools libva-dev libmfx-dev intel-media-va-driver-non-free vainfo
echo "export LIBVA_DRIVER_NAME=iHD" >> ~/.bashrc
source ~/.bashrc

View File

@@ -1,7 +0,0 @@
#!/bin/sh
curl -L https://repositories.intel.com/graphics/intel-graphics.key | sudo apt-key add -
sudo apt-add-repository 'deb [arch=amd64] https://repositories.intel.com/graphics/ubuntu focal main'
sudo apt-get update
sudo apt-get install -y -q --no-install-recommends clinfo intel-opencl-icd intel-media-va-driver-non-free

View File

@@ -1,70 +0,0 @@
#!/bin/sh
wget https://download.amovlab.com/model/deps/opencv-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_contrib-4.7.0.zip
wget https://download.amovlab.com/model/deps/opencv_cache_x86-4.7.0.zip
current_dir=$(pwd)
package_dir="."
mkdir ~/opencv_build
if [ ! -d ""$package_dir"" ];then
echo "\033[31m[ERROR]: $package_dir not exist!: \033[0m"
exit 1
fi
# sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
# sudo add-apt-repository "deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe"
sudo apt update
sudo apt install -y build-essential
sudo apt install -y cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32
sudo apt update
sudo apt install -y libjasper1 libjasper-dev
sudo apt install -y python3-dev python3-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev
sudo apt install -y libdc1394-22-dev
sudo apt install -y libcurl4 build-essential pkg-config cmake libopenblas-dev libeigen3-dev \
libtbb-dev libavcodec-dev libavformat-dev libgstreamer-plugins-base1.0-dev \
libgstreamer1.0-dev libswscale-dev libgtk-3-dev libpng-dev libjpeg-dev \
libcanberra-gtk-module libcanberra-gtk3-module
echo "\033[32m[INFO]:\033[0m unzip opencv-4.7.0.zip ..."
unzip -q -o $package_dir/opencv-4.7.0.zip -d ~/opencv_build
echo "\033[32m[INFO]:\033[0m unzip opencv_contrib-4.7.0.zip ..."
unzip -q -o $package_dir/opencv_contrib-4.7.0.zip -d ~/opencv_build
echo "\033[32m[INFO]:\033[0m unzip opencv_cache_x86-4.7.0.zip ..."
unzip -q -o $package_dir/opencv_cache_x86-4.7.0.zip -d ~/opencv_build
sudo rm opencv-4.7.0.zip
sudo rm opencv_contrib-4.7.0.zip
sudo rm opencv_cache_x86-4.7.0.zip
cd ~/opencv_build/opencv-4.7.0
mkdir .cache
cp -r ~/opencv_build/opencv_cache_x86-4.7.0/* ~/opencv_build/opencv-4.7.0/.cache/
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release \
-D WITH_CUDA=OFF \
-D OPENCV_ENABLE_NONFREE=ON \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.7.0/modules ..
make -j2
sudo make install
cd
sudo rm -r ~/opencv_build
cd ${current_dir}

View File

@@ -1,20 +0,0 @@
#!/bin/sh
sudo mkdir /opt/intel
current_dir=$(pwd)
cd ${HOME}/Downloads
curl -L https://storage.openvinotoolkit.org/repositories/openvino/packages/2022.3.1/linux/l_openvino_toolkit_ubuntu20_2022.3.1.9227.cf2c7da5689_x86_64.tgz --output openvino_2022.3.1.tgz
tar -xf openvino_2022.3.1.tgz
sudo mv l_openvino_toolkit_ubuntu20_2022.3.1.9227.cf2c7da5689_x86_64 /opt/intel/openvino_2022.3.1
cd /opt/intel/openvino_2022.3.1
sudo -E ./install_dependencies/install_openvino_dependencies.sh
cd /opt/intel
sudo ln -s openvino_2022.3.1 openvino_2022
echo "source /opt/intel/openvino_2022/setupvars.sh" >> ~/.bashrc
source ~/.bashrc
cd ${current_dir}

View File

@@ -1,22 +0,0 @@
#!/bin/sh
current_dir=$(pwd)
cd ${HOME}/SpireCV
git clone https://gitee.com/jario-jin/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
mkdir build
cd build
cmake ..
make -j4
cd ..
cd ..
mkdir ZLM
cd ZLM
cp ../ZLMediaKit/release/linux/Debug/MediaServer .
cp ../ZLMediaKit/release/linux/Debug/config.ini .
cd ${current_dir}

View File

@@ -379,7 +379,7 @@ void _load_all_json(std::string json_fn, JsonValue& value, JsonAllocator& alloca
}
fin.close();
// std::cout << json_str << std::endl;
char source[1024 * 256]; // 256K
char source[1024 * 1024]; // 1M
char *endptr;
strcpy(source, json_str.c_str());

View File

@@ -6,10 +6,6 @@
#include <ctime>
#include <chrono>
#include <fstream>
#include <dirent.h>
#include <opencv2/opencv.hpp>
#include <unordered_map>
using namespace std;
@@ -29,15 +25,6 @@ bool _is_file_exist(std::string& fn)
return f.good();
}
bool _comp_str_greater(const std::string& a, const std::string& b)
{
return a > b;
}
bool _comp_str_lesser(const std::string& a, const std::string& b)
{
return a < b;
}
void _get_sys_time(TimeInfo& t_info)
{
@@ -149,56 +136,4 @@ int _comp_str_idx(const std::string& in_str, const std::string* str_list, int le
return -1;
}
void _list_dir(std::string dir, std::vector<std::string>& files, std::string suffixs, std::string prefix, bool r) {
// assert(_endswith(dir, "/") || _endswith(dir, "\\"));
DIR *pdir;
struct dirent *ent;
string childpath;
string absolutepath;
pdir = opendir(dir.c_str());
assert(pdir != NULL);
vector<string> suffixd(0);
if (!suffixs.empty() && suffixs != "") {
suffixd = _split(suffixs, "|");
}
while ((ent = readdir(pdir)) != NULL) {
if (ent->d_type & DT_DIR) {
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
continue;
}
if (r) { // If need to traverse subdirectories
childpath = dir + ent->d_name;
_list_dir(childpath, files);
}
}
else {
if (suffixd.size() > 0) {
bool can_push = false, cancan_push = true;
for (int i = 0; i < (int)suffixd.size(); i++) {
if (_endswith(ent->d_name, suffixd[i]))
can_push = true;
}
if (prefix.size() > 0) {
if (!_startswith(ent->d_name, prefix))
cancan_push = false;
}
if (can_push && cancan_push) {
absolutepath = dir + ent->d_name;
files.push_back(ent->d_name); // filepath
}
}
else {
absolutepath = dir + ent->d_name;
files.push_back(ent->d_name); // filepath
}
}
}
sort(files.begin(), files.end()); //sort names
}
}

View File

@@ -24,13 +24,10 @@ bool _startswith(const std::string& str, const std::string& start);
bool _endswith(const std::string& str, const std::string& end);
std::string _trim(const std::string& str);
int _comp_str_idx(const std::string& in_str, const std::string* str_list, int len);
bool _comp_str_greater(const std::string& a, const std::string& b);
bool _comp_str_lesser(const std::string& a, const std::string& b);
/************* file-related functions ***************/
std::string _get_home();
bool _is_file_exist(std::string& fn);
void _list_dir(std::string dir, std::vector<std::string>& files, std::string suffixs="", std::string prefix="", bool r=false);
}

View File

@@ -0,0 +1,106 @@
/*
* @Description:
* @Author: L LC @amov
* @Date: 2023-12-19 18:30:17
* @LastEditors: L LC @amov
* @LastEditTime: 2023-12-21 17:56:47
* @FilePath: /SpireCV/video_io/driver/sv_camera_G1.cpp
*/
#include "sv_camera_privately.h"
#include <fstream>
class sv_camera_G1 : public sv_p::CameraBase
{
private:
std::string _ip;
public:
bool setStream(const std::string &ip, uint16_t port);
sv::CameraType getType(void) { return sv::CameraType::G1; }
std::string getName(void) { return _ip; }
bool open(void);
sv_camera_G1(int timeOut);
~sv_camera_G1();
static CameraBase *creat(int timeOut)
{
return new sv_camera_G1(timeOut);
}
};
sv_camera_G1::sv_camera_G1(int timeOut) : sv_p::CameraBase(timeOut)
{
}
bool sv_camera_G1::setStream(const std::string &ip, uint16_t port)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_ip = ip;
ret = true;
}
return ret;
}
const static uint32_t imageHList[3] = {1520, 1080, 720};
const static uint32_t imageWList[3] = {2704, 1920, 1280};
// 无论如何都用gst打开 因此安装的时候必须安装gst
bool sv_camera_G1::open(void)
{
bool ret = false;
std::ostringstream pipeline;
pipeline << "rtspsrc location = rtsp://" << this->_ip << ":554/H264?W=";
// 判断尺寸是否合法 不合法则找最高画质进行缩放
uint8_t i;
for (i = 0; i < 3; i++)
{
if (imageHList[i] <= this->getH())
{
if (imageWList[i] <= this->getW())
{
break;
}
}
}
// 在范围内
if (i < 3)
{
pipeline << imageWList[i] << "&H=" << imageHList[i];
}
else
{
pipeline << imageWList[2] << "&H=" << imageHList[2];
}
pipeline << "&FPS=" << this->getExpectFps() << "&BR=4000000 latency=100 "
<< "! application/x-rtp,media=video ! rtph264depay ! parsebin ! ";
#ifdef PLATFORM_JETSON
pipeline << "nvv4l2decoder enable-max-performancegst=1 \
! nvvidconv ! video/x-raw,format=(string)BGRx"
<< ",width=(int)" << this->getW()
<< ",height=(int)" << this->getH();
#else
pipeline << "avdec_h264 ! videoscale ! video/x-raw"
<< ",width=(int)" << this->getW()
<< ",height=(int)" << this->getH();
#endif
pipeline << " ! videoconvert ! video/x-raw,format=(string)BGR ! appsink sync=false";
if (this->cap.open(pipeline.str(), cv::CAP_GSTREAMER))
{
// 开启读取线程
std::thread readLoop(&CameraBase::readThread, this);
this->readThreadHandle = readLoop.native_handle();
readLoop.detach();
ret = true;
}
return ret;
}

View File

@@ -0,0 +1,85 @@
/*
* @Description:
* @Author: L LC @amov
* @Date: 2023-12-19 18:30:17
* @LastEditors: L LC @amov
* @LastEditTime: 2023-12-21 17:57:02
* @FilePath: /SpireCV/video_io/driver/sv_camera_GX40.cpp
*/
#include "sv_camera_privately.h"
#include <fstream>
class sv_camera_GX40 : public sv_p::CameraBase
{
private:
std::string _ip;
uint16_t _port = 554;
public:
bool setStream(const std::string &ip, uint16_t port);
sv::CameraType getType(void) { return sv::CameraType::GX40; }
std::string getName(void) { return _ip; }
bool open(void);
sv_camera_GX40(int timeOut);
~sv_camera_GX40();
static CameraBase *creat(int timeOut)
{
return new sv_camera_GX40(timeOut);
}
};
sv_camera_GX40::sv_camera_GX40(int timeOut) : sv_p::CameraBase(timeOut)
{
}
bool sv_camera_GX40::setStream(const std::string &ip, uint16_t port)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_ip = ip;
this->_port = port;
ret = true;
}
return ret;
}
// 无论如何都用gst打开 因此安装的时候必须安装gst
bool sv_camera_GX40::open(void)
{
bool ret = false;
std::ostringstream pipeline;
pipeline << "rtspsrc location = rtsp://user:0000@" << this->_ip << ":" << this->_port
<< "/cam/realmonitor?channel=1&subtype=0 latency=100 ! application/x-rtp,media=video ! "
<< "rtph265depay ! parsebin ! ";
#ifdef PLATFORM_JETSON
pipeline << "nvv4l2decoder ! nvvidconv flip-method=4 ! ";
#else
pipeline << "avdec_h265 ! videoscale ! ";
#endif
pipeline << "video/x-raw,format=(string)BGRx"
<< ",width=(int)" << this->getW()
<< ",height=(int)" << this->getH()
<< " ";
#ifndef PLATFORM_JETSON
pipeline << "! videoflip video-direction=4 ";
#endif
pipeline << " ! videoconvert ! video/x-raw,format=(string)BGR ! appsink sync=false";
if (this->cap.open(pipeline.str(), cv::CAP_GSTREAMER))
{
// 开启读取线程
std::thread readLoop(&CameraBase::readThread, this);
this->readThreadHandle = readLoop.native_handle();
readLoop.detach();
ret = true;
}
return ret;
}

View File

@@ -0,0 +1,78 @@
/*
* @Description:
* @Author: L LC @amov
* @Date: 2023-12-19 18:30:17
* @LastEditors: L LC @amov
* @LastEditTime: 2023-12-21 17:57:07
* @FilePath: /SpireCV/video_io/driver/sv_camera_MC1.cpp
*/
#include "sv_camera_privately.h"
#include <fstream>
class sv_camera_MC1 : public sv_p::CameraBase
{
private:
int _index = -2;
public:
bool setIndex(int index);
sv::CameraType getType(void) { return sv::CameraType::MC1; }
bool open(void);
sv_camera_MC1(int timeOut);
~sv_camera_MC1();
static CameraBase *creat(int timeOut)
{
#ifdef PLATFORM_JETSON
return new sv_camera_MC1(timeOut);
#else
throw std::runtime_error("SpireCV (101) Camera not supported except allspark");
return nullptr;
#endif
}
};
sv_camera_MC1::sv_camera_MC1(int timeOut) : sv_p::CameraBase(timeOut)
{
}
bool sv_camera_MC1::setIndex(int index)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_index = index;
ret = true;
}
return ret;
}
// 普通的mipi相机 采用 v4l2 框架打开
bool sv_camera_MC1::open(void)
{
bool ret = false;
std::ostringstream pipeline;
pipeline << "nvarguscamerasrc sensor-id=" << this->_index;
pipeline << " ! video/x-raw,video/x-raw(memory:NVMM),"
<< "width=(int)" << this->getW()
<< "height=(int)" << this->getH()
<< "framerate=" << this->getExpectFps() << "/1 !"
<< " nvvidconv flip-method=0 ! video/x-raw,format=(string)BGRx !"
<< " videoconvert ! video/x-raw, format=(string)BGR ! appsink";
if (this->cap.open(pipeline.str(), cv::CAP_GSTREAMER))
{
// 开启读取线程
std::thread readLoop(&CameraBase::readThread, this);
this->readThreadHandle = readLoop.native_handle();
readLoop.detach();
ret = true;
}
return ret;
}

View File

@@ -0,0 +1,149 @@
/*
* @Description:
* @Author: L LC @amov
* @Date: 2023-12-21 10:45:50
* @LastEditors: L LC @amov
* @LastEditTime: 2023-12-21 17:57:30
* @FilePath: /SpireCV/video_io/driver/sv_camera_V4L2s.cpp
*/
#include "sv_camera_privately.h"
class sv_camera_V4L2 : public sv_p::CameraBase
{
private:
int _index = -1;
std::string _name = "\0";
public:
bool setName(const std::string &name);
bool setIndex(int index);
virtual sv::CameraType getType(void) { return sv::CameraType::V4L2CAM; }
std::string getName(void) { return this->_name; }
bool open(void);
sv_camera_V4L2(int timeOut);
~sv_camera_V4L2();
static CameraBase *creat(int timeOut)
{
return new sv_camera_V4L2(timeOut);
}
};
sv_camera_V4L2::sv_camera_V4L2(int timeOut) : sv_p::CameraBase(timeOut)
{
}
bool sv_camera_V4L2::setName(const std::string &name)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_name = name;
ret = true;
}
return ret;
}
bool sv_camera_V4L2::setIndex(int index)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_index = index;
ret = true;
}
return ret;
}
bool sv_camera_V4L2::open(void)
{
bool ret = false;
if (this->_index >= 0)
{
ret = this->cap.open(this->_index, cv::CAP_V4L2);
}
if (!ret)
{
if (this->_name != "\0")
{
ret = this->cap.open(this->_name, cv::CAP_V4L2);
}
}
if (ret)
{
// 设置属性
this->setFps(this->getExpectFps());
this->setBrightness(this->getBrightness());
this->setContrast(this->getContrast());
this->setSaturation(this->getSaturation());
this->setHue(this->getHue());
this->setExposure(this->getExposure());
// 开启读取线程
std::thread readLoop(&CameraBase::readThread, this);
this->readThreadHandle = readLoop.native_handle();
readLoop.detach();
}
return ret;
}
class sv_camera_WEBCAM : public sv_camera_V4L2
{
public:
sv::CameraType getType(void) { return sv::CameraType::WEBCAM; }
sv_camera_WEBCAM(int timeOut);
~sv_camera_WEBCAM();
static CameraBase *creat(int timeOut)
{
return new sv_camera_WEBCAM(timeOut);
}
};
sv_camera_WEBCAM::sv_camera_WEBCAM(int timeOut) : sv_camera_V4L2(timeOut)
{
}
class sv_camera_Q10 : public sv_camera_V4L2
{
public:
sv::CameraType getType(void) { return sv::CameraType::Q10; }
sv_camera_Q10(int timeOut);
~sv_camera_Q10();
static CameraBase *creat(int timeOut)
{
return new sv_camera_Q10(timeOut);
}
};
sv_camera_Q10::sv_camera_Q10(int timeOut) : sv_camera_V4L2(timeOut)
{
}
class sv_camera_NONE : public sv_camera_V4L2
{
public:
sv::CameraType getType(void) { return sv::CameraType::NONE; }
sv_camera_NONE(int timeOut);
~sv_camera_NONE();
static CameraBase *creat(int timeOut)
{
return new sv_camera_NONE(timeOut);
}
};
sv_camera_NONE::sv_camera_NONE(int timeOut) : sv_camera_V4L2(timeOut)
{
}

View File

@@ -0,0 +1,79 @@
/*
* @Description:
* @Author: L LC @amov
* @Date: 2023-12-21 11:30:40
* @LastEditors: L LC @amov
* @LastEditTime: 2023-12-21 17:56:34
* @FilePath: /SpireCV/video_io/driver/sv_camera_file.cpp
*/
#include "sv_camera_privately.h"
class sv_camera_FILE : public sv_p::CameraBase
{
private:
std::string _name = "\0";
public:
bool setName(const std::string &name);
virtual sv::CameraType getType(void) { return sv::CameraType::VIDEOFILE; }
std::string getName(void) { return this->_name; }
bool open(void);
bool read(cv::Mat &image)
{
return this->cap.read(image);
}
bool readNoBlock(cv::Mat &image)
{
return this->read(image);
}
sv_camera_FILE(int timeOut);
~sv_camera_FILE();
static CameraBase *creat(int timeOut)
{
return new sv_camera_FILE(timeOut);
}
};
sv_camera_FILE::sv_camera_FILE(int timeOut) : sv_p::CameraBase(timeOut)
{
}
bool sv_camera_FILE::setName(const std::string &name)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_name = name;
ret = true;
}
return ret;
}
bool sv_camera_FILE::open(void)
{
bool ret = false;
if (this->_name != "\0")
{
ret = this->cap.open(this->_name);
}
if (ret)
{
// 设置属性
this->setFps(this->getExpectFps());
this->setBrightness(this->getBrightness());
this->setContrast(this->getContrast());
this->setSaturation(this->getSaturation());
this->setHue(this->getHue());
this->setExposure(this->getExposure());
}
return ret;
}

View File

@@ -0,0 +1,95 @@
/*
* @Description:
* @Author: L LC @amov
* @Date: 2023-12-19 18:30:17
* @LastEditors: L LC @amov
* @LastEditTime: 2023-12-21 17:57:12
* @FilePath: /SpireCV/video_io/driver/sv_camera_mipi.cpp
*/
#include "sv_camera_privately.h"
#include <fstream>
class sv_camera_MIPI : public sv_p::CameraBase
{
private:
int _index = -2;
std::string _name = "\0";
public:
bool setName(const std::string &name);
bool setIndex(int index);
sv::CameraType getType(void) { return sv::CameraType::MIPI; }
std::string getName(void) { return _name; }
bool open(void);
sv_camera_MIPI(int timeOut);
~sv_camera_MIPI();
static CameraBase *creat(int timeOut)
{
return new sv_camera_MIPI(timeOut);
}
};
sv_camera_MIPI::sv_camera_MIPI(int timeOut) : sv_p::CameraBase(timeOut)
{
}
bool sv_camera_MIPI::setName(const std::string &name)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_name = name;
ret = true;
}
return ret;
}
bool sv_camera_MIPI::setIndex(int index)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_index = index;
ret = true;
}
return ret;
}
// 普通的mipi相机 采用 v4l2 框架打开
bool sv_camera_MIPI::open(void)
{
bool ret = false;
std::ostringstream pipeline;
pipeline << "v4l2src ";
if (this->_name != "\0")
{
pipeline << "device=" << this->_name << " !";
}
else if (this->_index != -2)
{
pipeline << "device-fd=" << this->_index << " !";
}
pipeline << " video/x-raw,format=(string)NV12,"
<< "width=(int)" << this->getW()
<< "height=(int)" << this->getH()
<< "framerate=" << this->getExpectFps() << "/1 !"
<< " videoconvert ! video/x-raw, format=(string)BGR ! appsink";
if (this->cap.open(pipeline.str(), cv::CAP_GSTREAMER))
{
// 开启读取线程
std::thread readLoop(&CameraBase::readThread, this);
this->readThreadHandle = readLoop.native_handle();
readLoop.detach();
ret = true;
}
return ret;
}

View File

@@ -0,0 +1,74 @@
/*
* @Description:
* @Author: L LC @amov
* @Date: 2023-12-21 11:30:40
* @LastEditors: L LC @amov
* @LastEditTime: 2023-12-21 17:57:22
* @FilePath: /SpireCV/video_io/driver/sv_camera_streaming.cpp
*/
#include "sv_camera_privately.h"
class sv_camera_Streaming : public sv_p::CameraBase
{
private:
std::string _name = "\0";
public:
bool setName(const std::string &name);
virtual sv::CameraType getType(void) { return sv::CameraType::STREAMING; }
std::string getName(void) { return this->_name; }
bool open(void);
sv_camera_Streaming(int timeOut);
~sv_camera_Streaming();
static CameraBase *creat(int timeOut)
{
return new sv_camera_Streaming(timeOut);
}
};
sv_camera_Streaming::sv_camera_Streaming(int timeOut) : sv_p::CameraBase(timeOut)
{
}
bool sv_camera_Streaming::setName(const std::string &name)
{
bool ret = false;
if (!this->cap.isOpened())
{
this->_name = name;
ret = true;
}
return ret;
}
bool sv_camera_Streaming::open(void)
{
bool ret = false;
if (this->_name != "\0")
{
ret = this->cap.open(this->_name);
}
if (ret)
{
// 设置属性
this->setFps(this->getExpectFps());
this->setBrightness(this->getBrightness());
this->setContrast(this->getContrast());
this->setSaturation(this->getSaturation());
this->setHue(this->getHue());
this->setExposure(this->getExposure());
// 开启读取线程
std::thread readLoop(&CameraBase::readThread, this);
this->readThreadHandle = readLoop.native_handle();
readLoop.detach();
}
return ret;
}

View File

@@ -1,50 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <chrono>
// 获取当前系统启动以来的毫秒数
static int64_t getCurTime()
{
// tv_sec (s) tv_nsec (ns-纳秒)
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return (now.tv_sec * 1000 + now.tv_nsec / 1000000);
}
struct VideoFrame
{
public:
enum VideoFrameType
{
BGR = 0,
RGB ,
YUV420P,
};
// VideoFrame(VideoFrameType type, int width, int height,int size)
VideoFrame(VideoFrameType type, int width, int height)
{
this->type = type;
this->width = width;
this->height = height;
this->size = width*height*3;
this->data = new uint8_t[this->size];
}
~VideoFrame()
{
delete[] this->data;
this->data = nullptr;
}
VideoFrameType type;
int size;
int width;
int height;
uint8_t *data;
};

View File

@@ -1,635 +0,0 @@
#include "bs_push_streamer.h"
/*
amov_rtsp
2914e3c44737811096c5e1797fe5373d12fcdd39
*/
// char av_error[AV_ERROR_MAX_STRING_SIZE] = { 0 };
// #define av_err2str(errnum) av_make_error_string(av_error, AV_ERROR_MAX_STRING_SIZE, errnum)
BsPushStreamer::BsPushStreamer()
{
}
BsPushStreamer::~BsPushStreamer()
{
mThread->join();
mThread = nullptr;
}
static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int width, int height)
{
AVBufferRef *hw_frames_ref;
AVHWFramesContext *frames_ctx = NULL;
int err = 0;
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx)))
{
fprintf(stderr, "Failed to create VAAPI frame context.\n");
return -1;
}
frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
frames_ctx->format = AV_PIX_FMT_VAAPI;
frames_ctx->sw_format = AV_PIX_FMT_NV12;
frames_ctx->width = width;
frames_ctx->height = height;
frames_ctx->initial_pool_size = 20;
if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0)
{
// fprintf(stderr, "Failed to initialize VAAPI frame context."
// "Error code: %s\n",av_err2str(err));
av_buffer_unref(&hw_frames_ref);
return err;
}
ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
if (!ctx->hw_frames_ctx)
err = AVERROR(ENOMEM);
av_buffer_unref(&hw_frames_ref);
return err;
}
bool BsPushStreamer::setup(std::string name, int width, int height, int fps, std::string encoder, int bitrate = 4)
{
if (!connect(name, width, height, fps, encoder, bitrate))
{
std::cout << "BsPushStreamer::setup error\n";
return false;
}
mVideoFrame = new VideoFrame(VideoFrame::BGR, width, height);
// std::cout << "BsStreamer::setup Success!\n";
start();
return true;
}
void BsPushStreamer::start()
{
mThread = new std::thread(BsPushStreamer::encodeVideoAndWriteStreamThread, this);
mThread->native_handle();
push_running = true;
}
bool BsPushStreamer::connect(std::string name, int width, int height, int fps, std::string encoder, int bitrate)
{
// 初始化上下文
if (avformat_alloc_output_context2(&mFmtCtx, NULL, "rtsp", name.c_str()) < 0)
{
std::cout << "avformat_alloc_output_context2 error\n";
return false;
}
// 初始化视频编码器
// AVCodec *videoCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
// AVCodec *videoCodec = avcodec_find_encoder_by_name("h264_nvenc");
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
NULL, NULL, 0);
AVCodec *videoCodec = avcodec_find_encoder_by_name(encoder.c_str());
if (!videoCodec)
{
// std::cout << fmt::format("Using encoder:[{}] error!\n", encoder);
videoCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!videoCodec)
{
std::cout << "avcodec_alloc_context3 error";
return false;
}
std::cout << "Using default H264 encoder!\n";
}
mVideoCodecCtx = avcodec_alloc_context3(videoCodec);
if (!mVideoCodecCtx)
{
std::cout << "avcodec_alloc_context3 error";
return false;
}
// 压缩视频bit位大小 300kB
int bit_rate = bitrate * 1024 * 1024 * 8;
// CBRConstant BitRate - 固定比特率
mVideoCodecCtx->flags |= AV_CODEC_FLAG_QSCALE;
mVideoCodecCtx->bit_rate = bit_rate;
mVideoCodecCtx->rc_min_rate = bit_rate;
mVideoCodecCtx->rc_max_rate = bit_rate;
mVideoCodecCtx->bit_rate_tolerance = bit_rate;
mVideoCodecCtx->codec_id = videoCodec->id;
// 不支持AV_PIX_FMT_BGR24直接进行编码
mVideoCodecCtx->pix_fmt = AV_PIX_FMT_VAAPI;
mVideoCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
mVideoCodecCtx->width = width;
mVideoCodecCtx->height = height;
mVideoCodecCtx->time_base = {1, fps};
mVideoCodecCtx->framerate = {fps, 1};
mVideoCodecCtx->gop_size = 12;
mVideoCodecCtx->max_b_frames = 0;
mVideoCodecCtx->thread_count = 1;
mVideoCodecCtx->sample_aspect_ratio = (AVRational){1, 1};
// 手动设置PPS
// unsigned char sps_pps[] = {
// 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x2a, 0x96, 0x35, 0x40, 0xf0, 0x04,
// 0x4f, 0xcb, 0x37, 0x01, 0x01, 0x01, 0x40, 0x00, 0x01, 0xc2, 0x00, 0x00, 0x57,
// 0xe4, 0x01, 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x3c, 0x80, 0x00
// };
AVDictionary *video_codec_options = NULL;
av_dict_set(&video_codec_options, "profile", "main", 0);
// av_dict_set(&video_codec_options, "preset", "superfast", 0);
av_dict_set(&video_codec_options, "tune", "fastdecode", 0);
if ((err = set_hwframe_ctx(mVideoCodecCtx, hw_device_ctx, width, height)) < 0)
{
std::cout << "set_hwframe_ctx error\n";
return false;
}
if (avcodec_open2(mVideoCodecCtx, videoCodec, &video_codec_options) < 0)
{
std::cout << "avcodec_open2 error\n";
return false;
}
mVideoStream = avformat_new_stream(mFmtCtx, videoCodec);
if (!mVideoStream)
{
std::cout << "avformat_new_stream error\n";
return false;
}
mVideoStream->id = mFmtCtx->nb_streams - 1;
// stream的time_base参数非常重要它表示将现实中的一秒钟分为多少个时间基, 在下面调用avformat_write_header时自动完成
avcodec_parameters_from_context(mVideoStream->codecpar, mVideoCodecCtx);
mVideoIndex = mVideoStream->id;
// open output url
av_dump_format(mFmtCtx, 0, name.c_str(), 1);
if (!(mFmtCtx->oformat->flags & AVFMT_NOFILE))
{
int ret = avio_open(&mFmtCtx->pb, name.c_str(), AVIO_FLAG_WRITE);
if (ret < 0)
{
// std::cout << fmt::format("avio_open error url: {}\n", name.c_str());
// std::cout << fmt::format("ret = {} : {}\n", ret, av_err2str(ret));
// std::cout << fmt::format("ret = {}\n", ret);
return false;
}
}
AVDictionary *fmt_options = NULL;
av_dict_set(&fmt_options, "bufsize", "1024", 0);
av_dict_set(&fmt_options, "rw_timeout", "30000000", 0); // 设置rtmp/http-flv连接超时单位 us
av_dict_set(&fmt_options, "stimeout", "30000000", 0); // 设置rtsp连接超时单位 us
av_dict_set(&fmt_options, "rtsp_transport", "tcp", 0);
mFmtCtx->video_codec_id = mFmtCtx->oformat->video_codec;
mFmtCtx->audio_codec_id = mFmtCtx->oformat->audio_codec;
// 调用该函数会将所有stream的time_base自动设置一个值通常是1/90000或1/1000这表示一秒钟表示的时间基长度
if (avformat_write_header(mFmtCtx, &fmt_options) < 0)
{
std::cout << "avformat_write_header error\n";
return false;
}
return true;
}
void BsPushStreamer::encodeVideoAndWriteStreamThread(void *arg)
{
// PushExecutor *executor = (PushExecutor *)arg;
BsPushStreamer *mBsPushStreamer = (BsPushStreamer *)arg;
int width = mBsPushStreamer->mVideoFrame->width;
int height = mBsPushStreamer->mVideoFrame->height;
// 未编码的视频帧bgr格式
// VideoFrame *videoFrame = NULL;
// 未编码视频帧队列当前长度
// int videoFrameQSize = 0;
AVFrame *hw_frame = NULL;
AVFrame *frame_nv12 = av_frame_alloc();
frame_nv12->format = AV_PIX_FMT_NV12;
frame_nv12->width = width;
frame_nv12->height = height;
int frame_nv12_buff_size = av_image_get_buffer_size(AV_PIX_FMT_NV12, width, height, 1);
uint8_t *frame_nv12_buff = (uint8_t *)av_malloc(frame_nv12_buff_size);
av_image_fill_arrays(
frame_nv12->data, frame_nv12->linesize,
frame_nv12_buff,
AV_PIX_FMT_NV12,
width, height, 1);
if (!(hw_frame = av_frame_alloc()))
{
std::cout << "Error while av_frame_alloc().\n";
}
if (av_hwframe_get_buffer(mBsPushStreamer->mVideoCodecCtx->hw_frames_ctx, hw_frame, 0) < 0)
{
std::cout << "Error while av_hwframe_get_buffer.\n";
}
if (!hw_frame->hw_frames_ctx)
{
std::cout << "Error while hw_frames_ctx.\n";
}
// 编码后的视频帧
AVPacket *pkt = av_packet_alloc();
int64_t encodeSuccessCount = 0;
int64_t frameCount = 0;
int64_t t1 = 0;
int64_t t2 = 0;
int ret = -1;
auto cnt_time = std::chrono::system_clock::now().time_since_epoch();
auto last_update_time = std::chrono::system_clock::now().time_since_epoch();
while (mBsPushStreamer->push_running)
{
// if (mBsPushStreamer->getVideoFrame(videoFrame, videoFrameQSize))
if (mBsPushStreamer->nd_push_frame)
{
mBsPushStreamer->nd_push_frame = false;
// frame_bgr 转 frame_nv12
//mBsPushStreamer->bgr24ToYuv420p(mBsPushStreamer->mVideoFrame->data, width, height, frame_nv12_buff);
mBsPushStreamer->Rgb2NV12(mBsPushStreamer->mVideoFrame->data, 3, width, height, frame_nv12_buff);
frame_nv12->pts = frame_nv12->pkt_dts = av_rescale_q_rnd(
frameCount,
mBsPushStreamer->mVideoCodecCtx->time_base,
mBsPushStreamer->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
frame_nv12->pkt_duration = av_rescale_q_rnd(
1,
mBsPushStreamer->mVideoCodecCtx->time_base,
mBsPushStreamer->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
frame_nv12->pkt_pos = -1;
hw_frame->pts = hw_frame->pkt_dts = av_rescale_q_rnd(
frameCount,
mBsPushStreamer->mVideoCodecCtx->time_base,
mBsPushStreamer->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
hw_frame->pkt_duration = av_rescale_q_rnd(
1,
mBsPushStreamer->mVideoCodecCtx->time_base,
mBsPushStreamer->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
hw_frame->pkt_pos = -1;
if (av_hwframe_transfer_data(hw_frame, frame_nv12, 0) < 0)
{
std::cout << "Error while transferring frame data to surface.\n";
}
t1 = getCurTime();
ret = avcodec_send_frame(mBsPushStreamer->mVideoCodecCtx, hw_frame);
if (ret >= 0)
{
ret = avcodec_receive_packet(mBsPushStreamer->mVideoCodecCtx, pkt);
if (ret >= 0)
{
t2 = getCurTime();
encodeSuccessCount++;
// 如果实际推流的是flv文件不会执行里面的fix_packet_pts
if (pkt->pts == AV_NOPTS_VALUE)
{
std::cout << "pkt->pts == AV_NOPTS_VALUE\n";
}
pkt->stream_index = mBsPushStreamer->mVideoIndex;
pkt->pos = -1;
pkt->duration = frame_nv12->pkt_duration;
ret = mBsPushStreamer->writePkt(pkt);
if (ret < 0)
{
// std::cout << fmt::format("writePkt : ret = {}\n", ret);
}
}
else
{
// std::cout << fmt::format("avcodec_receive_packet error : ret = {}\n", ret);
}
}
else
{
// std::cout << fmt::format("avcodec_send_frame error : ret = {}\n", ret);
}
frameCount++;
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
// std::cout << fmt::format("push_running is false!\n");
// std::cout << fmt::format("end stream!\n");
// av_write_trailer(mFmtCtx); //写文件尾
av_packet_unref(pkt);
pkt = NULL;
av_free(frame_nv12_buff);
frame_nv12_buff = NULL;
av_frame_free(&frame_nv12);
av_frame_unref(hw_frame);
frame_nv12 = NULL;
hw_frame = NULL;
}
int BsPushStreamer::writePkt(AVPacket *pkt)
{
mWritePkt_mtx.lock();
int ret = av_write_frame(mFmtCtx, pkt);
mWritePkt_mtx.unlock();
return ret;
}
bool BsPushStreamer::getVideoFrame(VideoFrame *&frame, int &frameQSize)
{
mRGB_VideoFrameQ_mtx.lock();
if (!mRGB_VideoFrameQ.empty())
{
frame = mRGB_VideoFrameQ.front();
mRGB_VideoFrameQ.pop();
frameQSize = mRGB_VideoFrameQ.size();
mRGB_VideoFrameQ_mtx.unlock();
return true;
}
else
{
frameQSize = 0;
mRGB_VideoFrameQ_mtx.unlock();
return false;
}
}
// void BsPushStreamer::pushVideoFrame(unsigned char *data, int width,int height)
void BsPushStreamer::stream(cv::Mat &image)
{
int size = image.cols * image.rows * image.channels();
//VideoFrame *frame = new VideoFrame(VideoFrame::BGR, image.cols, image.rows);
cv::Mat bgr = cv::Mat::zeros(image.size(), CV_8UC3);
cv::cvtColor(image, bgr, cv::COLOR_BGR2RGB);
memcpy(mVideoFrame->data, bgr.data, size);
mRGB_VideoFrameQ_mtx.lock();
nd_push_frame = true;
// mRGB_VideoFrameQ.push(frame);
mRGB_VideoFrameQ_mtx.unlock();
}
bool BsPushStreamer::videoFrameQisEmpty()
{
return mRGB_VideoFrameQ.empty();
}
unsigned char BsPushStreamer::clipValue(unsigned char x, unsigned char min_val, unsigned char max_val)
{
if (x > max_val)
{
return max_val;
}
else if (x < min_val)
{
return min_val;
}
else
{
return x;
}
}
bool BsPushStreamer::bgr24ToYuv420p(unsigned char *bgrBuf, int w, int h, unsigned char *yuvBuf)
{
unsigned char *ptrY, *ptrU, *ptrV, *ptrRGB;
memset(yuvBuf, 0, w * h * 3 / 2);
ptrY = yuvBuf;
ptrU = yuvBuf + w * h;
ptrV = ptrU + (w * h * 1 / 4);
unsigned char y, u, v, r, g, b;
for (int j = 0; j < h; ++j)
{
ptrRGB = bgrBuf + w * j * 3;
for (int i = 0; i < w; i++)
{
b = *(ptrRGB++);
g = *(ptrRGB++);
r = *(ptrRGB++);
y = (unsigned char)((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
u = (unsigned char)((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
v = (unsigned char)((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
*(ptrY++) = clipValue(y, 0, 255);
if (j % 2 == 0 && i % 2 == 0)
{
*(ptrU++) = clipValue(u, 0, 255);
}
else
{
if (i % 2 == 0)
{
*(ptrV++) = clipValue(v, 0, 255);
}
}
}
}
return true;
}
// https://software.intel.com/en-us/node/503873
// YCbCr Color Model:
// The YCbCr color space is used for component digital video and was developed as part of the ITU-R BT.601 Recommendation. YCbCr is a scaled and offset version of the YUV color space.
// The Intel IPP functions use the following basic equations [Jack01] to convert between R'G'B' in the range 0-255 and Y'Cb'Cr' (this notation means that all components are derived from gamma-corrected R'G'B'):
// Y' = 0.257*R' + 0.504*G' + 0.098*B' + 16
// Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
// Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
// Y' = 0.257*R' + 0.504*G' + 0.098*B' + 16
static float Rgb2Y(float r0, float g0, float b0)
{
float y0 = 0.257f * r0 + 0.504f * g0 + 0.098f * b0 + 16.0f;
return y0;
}
// U equals Cb'
// Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
static float Rgb2U(float r0, float g0, float b0)
{
float u0 = -0.148f * r0 - 0.291f * g0 + 0.439f * b0 + 128.0f;
return u0;
}
// V equals Cr'
// Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
static float Rgb2V(float r0, float g0, float b0)
{
float v0 = 0.439f * r0 - 0.368f * g0 - 0.071f * b0 + 128.0f;
return v0;
}
// Convert two rows from RGB to two Y rows, and one row of interleaved U,V.
// I0 and I1 points two sequential source rows.
// I0 -> rgbrgbrgbrgbrgbrgb...
// I1 -> rgbrgbrgbrgbrgbrgb...
// Y0 and Y1 points two sequential destination rows of Y plane.
// Y0 -> yyyyyy
// Y1 -> yyyyyy
// UV0 points destination rows of interleaved UV plane.
// UV0 -> uvuvuv
static void Rgb2NV12TwoRows(const unsigned char I0[],
const unsigned char I1[],
int step,
const int image_width,
unsigned char Y0[],
unsigned char Y1[],
unsigned char UV0[])
{
int x; // Column index
// Process 4 source pixels per iteration (2 pixels of row I0 and 2 pixels of row I1).
for (x = 0; x < image_width; x += 2)
{
// Load R,G,B elements from first row (and convert to float).
float r00 = (float)I0[x * step + 0];
float g00 = (float)I0[x * step + 1];
float b00 = (float)I0[x * step + 2];
// Load next R,G,B elements from first row (and convert to float).
float r01 = (float)I0[x * step + step + 0];
float g01 = (float)I0[x * step + step + 1];
float b01 = (float)I0[x * step + step + 2];
// Load R,G,B elements from second row (and convert to float).
float r10 = (float)I1[x * step + 0];
float g10 = (float)I1[x * step + 1];
float b10 = (float)I1[x * step + 2];
// Load next R,G,B elements from second row (and convert to float).
float r11 = (float)I1[x * step + step + 0];
float g11 = (float)I1[x * step + step + 1];
float b11 = (float)I1[x * step + step + 2];
// Calculate 4 Y elements.
float y00 = Rgb2Y(r00, g00, b00);
float y01 = Rgb2Y(r01, g01, b01);
float y10 = Rgb2Y(r10, g10, b10);
float y11 = Rgb2Y(r11, g11, b11);
// Calculate 4 U elements.
float u00 = Rgb2U(r00, g00, b00);
float u01 = Rgb2U(r01, g01, b01);
float u10 = Rgb2U(r10, g10, b10);
float u11 = Rgb2U(r11, g11, b11);
// Calculate 4 V elements.
float v00 = Rgb2V(r00, g00, b00);
float v01 = Rgb2V(r01, g01, b01);
float v10 = Rgb2V(r10, g10, b10);
float v11 = Rgb2V(r11, g11, b11);
// Calculate destination U element: average of 2x2 "original" U elements.
float u0 = (u00 + u01 + u10 + u11) * 0.25f;
// Calculate destination V element: average of 2x2 "original" V elements.
float v0 = (v00 + v01 + v10 + v11) * 0.25f;
// Store 4 Y elements (two in first row and two in second row).
Y0[x + 0] = (unsigned char)(y00 + 0.5f);
Y0[x + 1] = (unsigned char)(y01 + 0.5f);
Y1[x + 0] = (unsigned char)(y10 + 0.5f);
Y1[x + 1] = (unsigned char)(y11 + 0.5f);
// Store destination U element.
UV0[x + 0] = (unsigned char)(u0 + 0.5f);
// Store destination V element (next to stored U element).
UV0[x + 1] = (unsigned char)(v0 + 0.5f);
}
}
// Convert image I from pixel ordered RGB to NV12 format.
// I - Input image in pixel ordered RGB format
// image_width - Number of columns of I
// image_height - Number of rows of I
// J - Destination "image" in NV12 format.
// I is pixel ordered RGB color format (size in bytes is image_width*image_height*3):
// RGBRGBRGBRGBRGBRGB
// RGBRGBRGBRGBRGBRGB
// RGBRGBRGBRGBRGBRGB
// RGBRGBRGBRGBRGBRGB
//
// J is in NV12 format (size in bytes is image_width*image_height*3/2):
// YYYYYY
// YYYYYY
// UVUVUV
// Each element of destination U is average of 2x2 "original" U elements
// Each element of destination V is average of 2x2 "original" V elements
//
// Limitations:
// 1. image_width must be a multiple of 2.
// 2. image_height must be a multiple of 2.
// 3. I and J must be two separate arrays (in place computation is not supported).
void BsPushStreamer::Rgb2NV12(const unsigned char I[], int step,
const int image_width,
const int image_height,
unsigned char J[])
{
// In NV12 format, UV plane starts below Y plane.
unsigned char *UV = &J[image_width * image_height];
// I0 and I1 points two sequential source rows.
const unsigned char *I0; // I0 -> rgbrgbrgbrgbrgbrgb...
const unsigned char *I1; // I1 -> rgbrgbrgbrgbrgbrgb...
// Y0 and Y1 points two sequential destination rows of Y plane.
unsigned char *Y0; // Y0 -> yyyyyy
unsigned char *Y1; // Y1 -> yyyyyy
// UV0 points destination rows of interleaved UV plane.
unsigned char *UV0; // UV0 -> uvuvuv
int y; // Row index
// In each iteration: process two rows of Y plane, and one row of interleaved UV plane.
for (y = 0; y < image_height; y += 2)
{
I0 = &I[y * image_width * step]; // Input row width is image_width*3 bytes (each pixel is R,G,B).
I1 = &I[(y + 1) * image_width * step];
Y0 = &J[y * image_width]; // Output Y row width is image_width bytes (one Y element per pixel).
Y1 = &J[(y + 1) * image_width];
UV0 = &UV[(y / 2) * image_width]; // Output UV row - width is same as Y row width.
// Process two source rows into: Two Y destination row, and one destination interleaved U,V row.
Rgb2NV12TwoRows(I0,
I1,
step,
image_width,
Y0,
Y1,
UV0);
}
}

View File

@@ -1,88 +0,0 @@
#pragma once
#include <iostream>
#include <thread>
#include <chrono>
// #include <fmt/core.h>
// #include <glog/logging.h>
#include <queue>
#include <mutex>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
// #include <libavutil/error.h>
#include <libswresample/swresample.h>
#include <libavutil/pixdesc.h>
#include <libavutil/hwcontext.h>
}
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include "bs_common.h"
using namespace cv;
class BsPushStreamer
{
public:
BsPushStreamer();
~BsPushStreamer();
// 用于初始化视频推流,仅调用一次
bool setup(std::string name, int width, int height, int fps, std::string encoder, int bitrate);
// 推流一帧图像,在循环中被调用
void stream(cv::Mat &image);
// 连接流媒体服务器
bool connect(std::string name, int width, int height, int fps, std::string encoder, int bitrate);
void start();
void stop() { push_running = false; };
// 编码视频帧并推流
static void encodeVideoAndWriteStreamThread(void *arg);
bool videoFrameQisEmpty();
int writePkt(AVPacket *pkt);
// 上下文
AVFormatContext *mFmtCtx = nullptr;
// 视频帧
AVCodecContext *mVideoCodecCtx = NULL;
AVStream *mVideoStream = NULL;
VideoFrame *mVideoFrame = NULL;
AVBufferRef *hw_device_ctx = NULL;
int err;
int mVideoIndex = -1;
// YAML::Node yaml_cfg;
private:
// 从mRGB_VideoFrameQ里面获取RGBframe
bool getVideoFrame(VideoFrame *&frame, int &frameQSize);
// bgr24转yuv420p
unsigned char clipValue(unsigned char x, unsigned char min_val, unsigned char max_val);
bool bgr24ToYuv420p(unsigned char *bgrBuf, int w, int h, unsigned char *yuvBuf);
void Rgb2NV12(const unsigned char I[], int step, const int image_width, const int image_height, unsigned char J[]);
bool push_running = false;
bool nd_push_frame = false;
// 视频帧
std::queue<VideoFrame *> mRGB_VideoFrameQ;
std::mutex mRGB_VideoFrameQ_mtx;
// 推流锁
std::mutex mWritePkt_mtx;
std::thread *mThread;
};

View File

@@ -1,655 +0,0 @@
#include "bs_video_saver.h"
/*
amov_rtsp
53248e16cc899903cf296df468977c60d7d73aa7
*/
BsVideoSaver::BsVideoSaver()
{
}
BsVideoSaver::~BsVideoSaver()
{
}
static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int width, int height)
{
AVBufferRef *hw_frames_ref;
AVHWFramesContext *frames_ctx = NULL;
int err = 0;
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx)))
{
fprintf(stderr, "Failed to create VAAPI frame context.\n");
return -1;
}
frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
frames_ctx->format = AV_PIX_FMT_VAAPI;
frames_ctx->sw_format = AV_PIX_FMT_NV12;
frames_ctx->width = width;
frames_ctx->height = height;
frames_ctx->initial_pool_size = 20;
if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0)
{
// fprintf(stderr, "Failed to initialize VAAPI frame context."
// "Error code: %s\n",av_err2str(err));
av_buffer_unref(&hw_frames_ref);
return err;
}
ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
if (!ctx->hw_frames_ctx)
err = AVERROR(ENOMEM);
av_buffer_unref(&hw_frames_ref);
return err;
}
bool BsVideoSaver::setup(std::string name, int width, int height, int fps, std::string encoder, int bitrate = 4)
{
// 重置状态然后初始化
this->width = width;
this->height = height;
// 线程停止
if (mThread != nullptr)
{
this->stop();
}
// 编码器重置
if (mVideoCodecCtx != NULL)
{
avcodec_free_context(&mVideoCodecCtx);
}
if (!this->init(name, width, height, fps, encoder, bitrate))
{
std::cout << "BsVideoSaver::setup error\n";
return false;
}
std::cout << "BsStreamer::setup Success!\n";
start();
return true;
}
void BsVideoSaver::start()
{
mThread = new std::thread(BsVideoSaver::encodeVideoAndSaveThread, this);
mThread->native_handle();
push_running = true;
}
void BsVideoSaver::stop()
{
if (mThread != nullptr)
{
push_running = false;
mThread->join();
mThread = nullptr;
}
}
bool BsVideoSaver::init(std::string name, int width, int height, int fps, std::string encoder, int bitrate)
{
// 初始化上下文
if (avformat_alloc_output_context2(&mFmtCtx, NULL, NULL, name.c_str()) < 0)
{
std::cout << "avformat_alloc_output_context2 error\n";
return false;
}
// 初始化视频编码器
// AVCodec *videoCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
// AVCodec *videoCodec = avcodec_find_encoder_by_name("h264_nvenc");
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
NULL, NULL, 0);
AVCodec *videoCodec = avcodec_find_encoder_by_name(encoder.c_str());
if (!videoCodec)
{
// std::cout << fmt::format("Using encoder:[{}] error!\n", encoder);
videoCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!videoCodec)
{
std::cout << "avcodec_alloc_context3 error";
return false;
}
std::cout << "Using default H264 encoder!\n";
}
mVideoCodecCtx = avcodec_alloc_context3(videoCodec);
if (!mVideoCodecCtx)
{
std::cout << "avcodec_alloc_context3 error";
return false;
}
// 压缩视频bit位大小 300kB
int bit_rate = bitrate * 1024 * 1024 * 8;
// CBRConstant BitRate - 固定比特率
mVideoCodecCtx->flags |= AV_CODEC_FLAG_QSCALE;
mVideoCodecCtx->bit_rate = bit_rate;
mVideoCodecCtx->rc_min_rate = bit_rate;
mVideoCodecCtx->rc_max_rate = bit_rate;
mVideoCodecCtx->bit_rate_tolerance = bit_rate;
mVideoCodecCtx->codec_id = videoCodec->id;
// 不支持AV_PIX_FMT_BGR24直接进行编码
mVideoCodecCtx->pix_fmt = AV_PIX_FMT_VAAPI;
mVideoCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
mVideoCodecCtx->width = width;
mVideoCodecCtx->height = height;
mVideoCodecCtx->time_base = {1, fps};
mVideoCodecCtx->framerate = {fps, 1};
mVideoCodecCtx->gop_size = 12;
mVideoCodecCtx->max_b_frames = 0;
mVideoCodecCtx->thread_count = 1;
// mVideoCodecCtx->sample_aspect_ratio = (AVRational){1, 1};
AVDictionary *video_codec_options = NULL;
av_dict_set(&video_codec_options, "profile", "main", 0);
// av_dict_set(&video_codec_options, "preset", "superfast", 0);
av_dict_set(&video_codec_options, "tune", "fastdecode", 0);
if ((err = set_hwframe_ctx(mVideoCodecCtx, hw_device_ctx, width, height)) < 0)
{
std::cout << "set_hwframe_ctx error\n";
return false;
}
if (avcodec_open2(mVideoCodecCtx, videoCodec, &video_codec_options) < 0)
{
std::cout << "avcodec_open2 error\n";
return false;
}
mVideoStream = avformat_new_stream(mFmtCtx, videoCodec);
if (!mVideoStream)
{
std::cout << "avformat_new_stream error\n";
return false;
}
mVideoStream->id = mFmtCtx->nb_streams - 1;
// stream的time_base参数非常重要它表示将现实中的一秒钟分为多少个时间基, 在下面调用avformat_write_header时自动完成
avcodec_parameters_from_context(mVideoStream->codecpar, mVideoCodecCtx);
mVideoIndex = mVideoStream->id;
// open output url
av_dump_format(mFmtCtx, 0, name.c_str(), 1);
if (!(mFmtCtx->oformat->flags & AVFMT_NOFILE))
{
int ret = avio_open(&mFmtCtx->pb, name.c_str(), AVIO_FLAG_WRITE);
if (ret < 0)
{
// std::cout << fmt::format("avio_open error url: {}\n", name.c_str());
// std::cout << fmt::format("ret = {} : {}\n", ret, av_err2str(ret));
// std::cout << fmt::format("ret = {}\n", ret);
return false;
}
}
AVDictionary *fmt_options = NULL;
av_dict_set(&fmt_options, "bufsize", "1024", 0);
mFmtCtx->video_codec_id = mFmtCtx->oformat->video_codec;
mFmtCtx->audio_codec_id = mFmtCtx->oformat->audio_codec;
// 调用该函数会将所有stream的time_base自动设置一个值通常是1/90000或1/1000这表示一秒钟表示的时间基长度
if (avformat_write_header(mFmtCtx, &fmt_options) < 0)
{
std::cout << "avformat_write_header error\n";
return false;
}
return true;
}
void BsVideoSaver::encodeVideoAndSaveThread(void *arg)
{
// PushExecutor *executor = (PushExecutor *)arg;
BsVideoSaver *mBsVideoSaver = (BsVideoSaver *)arg;
int width = mBsVideoSaver->width;
int height = mBsVideoSaver->height;
// 未编码的视频帧bgr格式
VideoFrame *videoFrame = NULL;
// 未编码视频帧队列当前长度
int videoFrameQSize = 0;
AVFrame *hw_frame = NULL;
AVFrame *frame_nv12 = av_frame_alloc();
frame_nv12->format = AV_PIX_FMT_NV12;
frame_nv12->width = width;
frame_nv12->height = height;
int frame_nv12_buff_size = av_image_get_buffer_size(AV_PIX_FMT_NV12, width, height, 1);
uint8_t *frame_nv12_buff = (uint8_t *)av_malloc(frame_nv12_buff_size);
av_image_fill_arrays(
frame_nv12->data, frame_nv12->linesize,
frame_nv12_buff,
AV_PIX_FMT_NV12,
width, height, 1);
/* read data into software frame, and transfer them into hw frame */
// sw_frame->width = width;
// sw_frame->height = height;
// sw_frame->format = AV_PIX_FMT_NV12;
if (!(hw_frame = av_frame_alloc()))
{
std::cout << "Error while av_frame_alloc().\n";
}
if (av_hwframe_get_buffer(mBsVideoSaver->mVideoCodecCtx->hw_frames_ctx, hw_frame, 0) < 0)
{
std::cout << "Error while av_hwframe_get_buffer.\n";
}
if (!hw_frame->hw_frames_ctx)
{
std::cout << "Error while hw_frames_ctx.\n";
}
// 编码后的视频帧
AVPacket *pkt = av_packet_alloc();
int64_t encodeSuccessCount = 0;
int64_t frameCount = 0;
int64_t t1 = 0;
int64_t t2 = 0;
int ret = -1;
while (mBsVideoSaver->push_running)
{
if (mBsVideoSaver->getVideoFrame(videoFrame, videoFrameQSize))
{
// frame_bgr 转 frame_nv12
//mBsVideoSaver->bgr24ToYuv420p(videoFrame->data, width, height, frame_nv12_buff);
mBsVideoSaver->Rgb2NV12(videoFrame->data, 3, width, height, frame_nv12_buff);
// RGB2YUV_NV12(videoFrame->data, frame_nv12_buff, width, height );
frame_nv12->pts = frame_nv12->pkt_dts = av_rescale_q_rnd(
frameCount,
mBsVideoSaver->mVideoCodecCtx->time_base,
mBsVideoSaver->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
frame_nv12->pkt_duration = av_rescale_q_rnd(
1,
mBsVideoSaver->mVideoCodecCtx->time_base,
mBsVideoSaver->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
frame_nv12->pkt_pos = frameCount;
hw_frame->pts = hw_frame->pkt_dts = av_rescale_q_rnd(
frameCount,
mBsVideoSaver->mVideoCodecCtx->time_base,
mBsVideoSaver->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
hw_frame->pkt_duration = av_rescale_q_rnd(
1,
mBsVideoSaver->mVideoCodecCtx->time_base,
mBsVideoSaver->mVideoStream->time_base,
(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
hw_frame->pkt_pos = frameCount;
if (av_hwframe_transfer_data(hw_frame, frame_nv12, 0) < 0)
{
std::cout << "Error while transferring frame data to surface.\n";
}
t1 = getCurTime();
ret = avcodec_send_frame(mBsVideoSaver->mVideoCodecCtx, hw_frame);
if (ret >= 0)
{
ret = avcodec_receive_packet(mBsVideoSaver->mVideoCodecCtx, pkt);
if (ret >= 0)
{
t2 = getCurTime();
encodeSuccessCount++;
pkt->stream_index = mBsVideoSaver->mVideoIndex;
pkt->pos = frameCount;
pkt->duration = frame_nv12->pkt_duration;
ret = mBsVideoSaver->writePkt(pkt);
if (ret < 0)
{
// std::cout << fmt::format("writePkt : ret = {}\n", ret);
}
}
else
{
// std::cout << fmt::format("avcodec_receive_packet error : ret = {}\n", ret);
}
}
else
{
// std::cout << fmt::format("avcodec_send_frame error : ret = {}\n", ret);
}
frameCount++;
// 释放资源
delete videoFrame;
videoFrame = NULL;
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
// std::cout << fmt::format("push_running is false!\n");
// std::cout << fmt::format("end stream!\n");
// 写文件尾
av_write_trailer(mBsVideoSaver->mFmtCtx);
av_packet_unref(pkt);
pkt = NULL;
av_free(frame_nv12_buff);
frame_nv12_buff = NULL;
av_frame_free(&frame_nv12);
av_frame_free(&hw_frame);
// av_frame_unref(frame_nv12);
frame_nv12 = NULL;
}
int BsVideoSaver::writePkt(AVPacket *pkt)
{
mWritePkt_mtx.lock();
int ret = av_write_frame(mFmtCtx, pkt);
mWritePkt_mtx.unlock();
return ret;
}
bool BsVideoSaver::getVideoFrame(VideoFrame *&frame, int &frameQSize)
{
mRGB_VideoFrameQ_mtx.lock();
if (!mRGB_VideoFrameQ.empty())
{
frame = mRGB_VideoFrameQ.front();
mRGB_VideoFrameQ.pop();
frameQSize = mRGB_VideoFrameQ.size();
mRGB_VideoFrameQ_mtx.unlock();
return true;
}
else
{
frameQSize = 0;
mRGB_VideoFrameQ_mtx.unlock();
return false;
}
}
void BsVideoSaver::write(cv::Mat &image)
{
int size = image.cols * image.rows * image.channels();
VideoFrame *frame = new VideoFrame(VideoFrame::BGR, image.cols, image.rows);
cv::Mat bgr = cv::Mat::zeros(image.size(), CV_8UC3);
cv::cvtColor(image, bgr, cv::COLOR_BGR2RGB);
memcpy(frame->data, bgr.data, size);
mRGB_VideoFrameQ_mtx.lock();
mRGB_VideoFrameQ.push(frame);
mRGB_VideoFrameQ_mtx.unlock();
}
bool BsVideoSaver::videoFrameQisEmpty()
{
return mRGB_VideoFrameQ.empty();
}
unsigned char BsVideoSaver::clipValue(unsigned char x, unsigned char min_val, unsigned char max_val)
{
if (x > max_val)
{
return max_val;
}
else if (x < min_val)
{
return min_val;
}
else
{
return x;
}
}
bool BsVideoSaver::bgr24ToYuv420p(unsigned char *bgrBuf, int w, int h, unsigned char *yuvBuf)
{
unsigned char *ptrY, *ptrU, *ptrV, *ptrRGB;
memset(yuvBuf, 0, w * h * 3 / 2);
ptrY = yuvBuf;
ptrU = yuvBuf + w * h;
ptrV = ptrU + (w * h * 1 / 4);
unsigned char y, u, v, r, g, b;
for (int j = 0; j < h; ++j)
{
ptrRGB = bgrBuf + w * j * 3;
for (int i = 0; i < w; i++)
{
b = *(ptrRGB++);
g = *(ptrRGB++);
r = *(ptrRGB++);
y = (unsigned char)((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
u = (unsigned char)((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
v = (unsigned char)((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
*(ptrY++) = clipValue(y, 0, 255);
if (j % 2 == 0 && i % 2 == 0)
{
*(ptrU++) = clipValue(u, 0, 255);
}
else
{
if (i % 2 == 0)
{
*(ptrV++) = clipValue(v, 0, 255);
}
}
}
}
return true;
}
//https://software.intel.com/en-us/node/503873
//YCbCr Color Model:
// The YCbCr color space is used for component digital video and was developed as part of the ITU-R BT.601 Recommendation. YCbCr is a scaled and offset version of the YUV color space.
// The Intel IPP functions use the following basic equations [Jack01] to convert between R'G'B' in the range 0-255 and Y'Cb'Cr' (this notation means that all components are derived from gamma-corrected R'G'B'):
// Y' = 0.257*R' + 0.504*G' + 0.098*B' + 16
// Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
// Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
//Y' = 0.257*R' + 0.504*G' + 0.098*B' + 16
static float Rgb2Y(float r0, float g0, float b0)
{
float y0 = 0.257f*r0 + 0.504f*g0 + 0.098f*b0 + 16.0f;
return y0;
}
//U equals Cb'
//Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
static float Rgb2U(float r0, float g0, float b0)
{
float u0 = -0.148f*r0 - 0.291f*g0 + 0.439f*b0 + 128.0f;
return u0;
}
//V equals Cr'
//Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
static float Rgb2V(float r0, float g0, float b0)
{
float v0 = 0.439f*r0 - 0.368f*g0 - 0.071f*b0 + 128.0f;
return v0;
}
//Convert two rows from RGB to two Y rows, and one row of interleaved U,V.
//I0 and I1 points two sequential source rows.
//I0 -> rgbrgbrgbrgbrgbrgb...
//I1 -> rgbrgbrgbrgbrgbrgb...
//Y0 and Y1 points two sequential destination rows of Y plane.
//Y0 -> yyyyyy
//Y1 -> yyyyyy
//UV0 points destination rows of interleaved UV plane.
//UV0 -> uvuvuv
static void Rgb2NV12TwoRows(const unsigned char I0[],
const unsigned char I1[],
int step,
const int image_width,
unsigned char Y0[],
unsigned char Y1[],
unsigned char UV0[])
{
int x; //Column index
//Process 4 source pixels per iteration (2 pixels of row I0 and 2 pixels of row I1).
for (x = 0; x < image_width; x += 2)
{
//Load R,G,B elements from first row (and convert to float).
float r00 = (float)I0[x*step + 0];
float g00 = (float)I0[x*step + 1];
float b00 = (float)I0[x*step + 2];
//Load next R,G,B elements from first row (and convert to float).
float r01 = (float)I0[x*step + step+0];
float g01 = (float)I0[x*step + step+1];
float b01 = (float)I0[x*step + step+2];
//Load R,G,B elements from second row (and convert to float).
float r10 = (float)I1[x*step + 0];
float g10 = (float)I1[x*step + 1];
float b10 = (float)I1[x*step + 2];
//Load next R,G,B elements from second row (and convert to float).
float r11 = (float)I1[x*step + step+0];
float g11 = (float)I1[x*step + step+1];
float b11 = (float)I1[x*step + step+2];
//Calculate 4 Y elements.
float y00 = Rgb2Y(r00, g00, b00);
float y01 = Rgb2Y(r01, g01, b01);
float y10 = Rgb2Y(r10, g10, b10);
float y11 = Rgb2Y(r11, g11, b11);
//Calculate 4 U elements.
float u00 = Rgb2U(r00, g00, b00);
float u01 = Rgb2U(r01, g01, b01);
float u10 = Rgb2U(r10, g10, b10);
float u11 = Rgb2U(r11, g11, b11);
//Calculate 4 V elements.
float v00 = Rgb2V(r00, g00, b00);
float v01 = Rgb2V(r01, g01, b01);
float v10 = Rgb2V(r10, g10, b10);
float v11 = Rgb2V(r11, g11, b11);
//Calculate destination U element: average of 2x2 "original" U elements.
float u0 = (u00 + u01 + u10 + u11)*0.25f;
//Calculate destination V element: average of 2x2 "original" V elements.
float v0 = (v00 + v01 + v10 + v11)*0.25f;
//Store 4 Y elements (two in first row and two in second row).
Y0[x + 0] = (unsigned char)(y00 + 0.5f);
Y0[x + 1] = (unsigned char)(y01 + 0.5f);
Y1[x + 0] = (unsigned char)(y10 + 0.5f);
Y1[x + 1] = (unsigned char)(y11 + 0.5f);
//Store destination U element.
UV0[x + 0] = (unsigned char)(u0 + 0.5f);
//Store destination V element (next to stored U element).
UV0[x + 1] = (unsigned char)(v0 + 0.5f);
}
}
//Convert image I from pixel ordered RGB to NV12 format.
//I - Input image in pixel ordered RGB format
//image_width - Number of columns of I
//image_height - Number of rows of I
//J - Destination "image" in NV12 format.
//I is pixel ordered RGB color format (size in bytes is image_width*image_height*3):
//RGBRGBRGBRGBRGBRGB
//RGBRGBRGBRGBRGBRGB
//RGBRGBRGBRGBRGBRGB
//RGBRGBRGBRGBRGBRGB
//
//J is in NV12 format (size in bytes is image_width*image_height*3/2):
//YYYYYY
//YYYYYY
//UVUVUV
//Each element of destination U is average of 2x2 "original" U elements
//Each element of destination V is average of 2x2 "original" V elements
//
//Limitations:
//1. image_width must be a multiple of 2.
//2. image_height must be a multiple of 2.
//3. I and J must be two separate arrays (in place computation is not supported).
void BsVideoSaver::Rgb2NV12(const unsigned char I[], int step,
const int image_width,
const int image_height,
unsigned char J[])
{
//In NV12 format, UV plane starts below Y plane.
unsigned char *UV = &J[image_width*image_height];
//I0 and I1 points two sequential source rows.
const unsigned char *I0; //I0 -> rgbrgbrgbrgbrgbrgb...
const unsigned char *I1; //I1 -> rgbrgbrgbrgbrgbrgb...
//Y0 and Y1 points two sequential destination rows of Y plane.
unsigned char *Y0; //Y0 -> yyyyyy
unsigned char *Y1; //Y1 -> yyyyyy
//UV0 points destination rows of interleaved UV plane.
unsigned char *UV0; //UV0 -> uvuvuv
int y; //Row index
//In each iteration: process two rows of Y plane, and one row of interleaved UV plane.
for (y = 0; y < image_height; y += 2)
{
I0 = &I[y*image_width*step]; //Input row width is image_width*3 bytes (each pixel is R,G,B).
I1 = &I[(y+1)*image_width*step];
Y0 = &J[y*image_width]; //Output Y row width is image_width bytes (one Y element per pixel).
Y1 = &J[(y+1)*image_width];
UV0 = &UV[(y/2)*image_width]; //Output UV row - width is same as Y row width.
//Process two source rows into: Two Y destination row, and one destination interleaved U,V row.
Rgb2NV12TwoRows(I0,
I1,
step,
image_width,
Y0,
Y1,
UV0);
}
}

View File

@@ -1,101 +0,0 @@
#pragma once
#include <iostream>
#include <thread>
#include <chrono>
#include <fmt/core.h>
// #include <glog/logging.h>
#include <queue>
#include <mutex>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
// #include <libavutil/error.h>
#include <libswresample/swresample.h>
#include <libavutil/pixdesc.h>
#include <libavutil/hwcontext.h>
}
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include "bs_common.h"
using namespace cv;
class BsVideoSaver
{
public:
BsVideoSaver();
~BsVideoSaver();
// 用于初始化视频推流,仅调用一次
bool setup(std::string name, int width, int height, int fps, std::string encoder, int bitrate);
// 推流一帧图像,在循环中被调用
void write(cv::Mat& image);
// 连接流媒体服务器
bool init(std::string name, int width, int height, int fps, std::string encoder, int bitrate);
void start();
void stop();
// 编码视频帧并推流
static void encodeVideoAndSaveThread(void* arg);
bool videoFrameQisEmpty();
int writePkt(AVPacket *pkt);
// 上下文
AVFormatContext *mFmtCtx = nullptr;
// 视频帧
AVCodecContext *mVideoCodecCtx = NULL;
AVStream *mVideoStream = NULL;
AVBufferRef *hw_device_ctx = NULL;
int err;
int mVideoIndex = -1;
private:
// 从mRGB_VideoFrameQ里面获取RGBframe
bool getVideoFrame(VideoFrame *&frame, int &frameQSize);
// bgr24转yuv420p
unsigned char clipValue(unsigned char x, unsigned char min_val, unsigned char max_val);
bool bgr24ToYuv420p(unsigned char *bgrBuf, int w, int h, unsigned char *yuvBuf);
void Rgb2NV12(const unsigned char I[], int step, const int image_width, const int image_height, unsigned char J[]);
// void RGB2YUV_NV12(uint8_t* rgbBufIn, uint8_t* yuvBufOut, int nWidth, int nHeight);
int width = -1;
int height = -1;
bool push_running = false;
bool nd_push_frame = false;
// 视频帧
std::queue<VideoFrame *> mRGB_VideoFrameQ;
std::mutex mRGB_VideoFrameQ_mtx;
// 推流锁
std::mutex mWritePkt_mtx;
std::thread* mThread = nullptr;
};

192
video_io/sv_camera.cpp Normal file
View File

@@ -0,0 +1,192 @@
#include "sv_camera_privately.h"
#include "sv_camera.h"
#include "driver/sv_camera_G1.cpp"
#include "driver/sv_camera_V4L2s.cpp"
#include "driver/sv_camera_file.cpp"
#include "driver/sv_camera_streaming.cpp"
#include "driver/sv_camera_mipi.cpp"
#include "driver/sv_camera_MC1.cpp"
#include "driver/sv_camera_GX40.cpp"
#include <map>
#include <iterator>
sv_p::CameraBase *cameraCreatEmpty(int timeOut)
{
throw std::runtime_error("SpireCV (101) Camera not supported");
return nullptr;
}
typedef sv_p::CameraBase *(*cameraCreat)(int timeOut);
static std::map<sv::CameraType, cameraCreat> svCameraList =
{
{sv::CameraType::NONE, sv_camera_NONE::creat},
{sv::CameraType::WEBCAM, sv_camera_WEBCAM::creat},
{sv::CameraType::V4L2CAM, sv_camera_V4L2::creat},
{sv::CameraType::VIDEOFILE, sv_camera_FILE::creat},
{sv::CameraType::STREAMING, sv_camera_Streaming::creat},
{sv::CameraType::MIPI, sv_camera_MIPI::creat},
{sv::CameraType::G1, sv_camera_G1::creat},
{sv::CameraType::Q10, sv_camera_Q10::creat},
{sv::CameraType::GX40, sv_camera_GX40::creat},
{sv::CameraType::MC1, sv_camera_MC1::creat},
{sv::CameraType::VIRTUAL, cameraCreatEmpty}};
static sv_p::CameraBase *svCreatCamera(sv::CameraType type, int timeOut)
{
std::map<sv::CameraType, cameraCreat>::iterator temp = svCameraList.find(type);
if (temp != svCameraList.end())
{
return temp->second(timeOut);
}
return nullptr;
}
sv::Camera::Camera(CameraType type, int timeOut)
{
this->dev = svCreatCamera(type, timeOut);
}
sv::Camera::~Camera()
{
// 休眠50ms 以便能退出线程
std::this_thread::sleep_for(std::chrono::milliseconds(50));
delete (sv_p::CameraBase *)dev;
}
sv_p::CameraBase::~CameraBase()
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
readThreadHandle = readThreadHandle == 0 ? 0 : pthread_cancel(readThreadHandle);
release();
}
bool sv::Camera::setStream(const std::string &ip, int port)
{
return ((sv_p::CameraBase *)dev)->setStream(ip, port);
}
bool sv::Camera::setName(const std::string &name)
{
return ((sv_p::CameraBase *)dev)->setName(name);
}
bool sv::Camera::setIndex(int index)
{
return ((sv_p::CameraBase *)dev)->setIndex(index);
}
bool sv::Camera::open(void)
{
return ((sv_p::CameraBase *)dev)->open();
}
bool sv::Camera::read(cv::Mat &image)
{
return ((sv_p::CameraBase *)dev)->read(image);
}
bool sv::Camera::readNoBlock(cv::Mat &image)
{
return ((sv_p::CameraBase *)dev)->readNoBlock(image);
}
void sv::Camera::release(void)
{
((sv_p::CameraBase *)dev)->release();
}
void sv::Camera::setWH(int width, int height)
{
((sv_p::CameraBase *)dev)->setWH(width, height);
}
void sv::Camera::setFps(int fps)
{
((sv_p::CameraBase *)dev)->setFps(fps);
}
void sv::Camera::setBrightness(double brightness)
{
((sv_p::CameraBase *)dev)->setBrightness(brightness);
}
void sv::Camera::setContrast(double contrast)
{
((sv_p::CameraBase *)dev)->setContrast(contrast);
}
void sv::Camera::setSaturation(double saturation)
{
((sv_p::CameraBase *)dev)->setSaturation(saturation);
}
void sv::Camera::setHue(double hue)
{
((sv_p::CameraBase *)dev)->setHue(hue);
}
void sv::Camera::setExposure(double exposure)
{
((sv_p::CameraBase *)dev)->setExposure(exposure);
}
bool sv::Camera::isActive(void)
{
return ((sv_p::CameraBase *)dev)->isActive();
}
sv::CameraType sv::Camera::getType(void)
{
return ((sv_p::CameraBase *)dev)->getType();
}
std::string sv::Camera::getName(void)
{
return ((sv_p::CameraBase *)dev)->getName();
}
int sv::Camera::getW(void)
{
return ((sv_p::CameraBase *)dev)->getW();
}
int sv::Camera::getH(void)
{
return ((sv_p::CameraBase *)dev)->getH();
}
int sv::Camera::getExpectFps(void)
{
return ((sv_p::CameraBase *)dev)->getExpectFps();
}
double sv::Camera::getFps(void)
{
return ((sv_p::CameraBase *)dev)->getFps();
}
double sv::Camera::getBrightness(void)
{
return ((sv_p::CameraBase *)dev)->getBrightness();
}
double sv::Camera::getContrast(void)
{
return ((sv_p::CameraBase *)dev)->getContrast();
}
double sv::Camera::getSaturation(void)
{
return ((sv_p::CameraBase *)dev)->getSaturation();
}
double sv::Camera::getHue(void)
{
return ((sv_p::CameraBase *)dev)->getHue();
}
double sv::Camera::getExposure(void)
{
return ((sv_p::CameraBase *)dev)->getExposure();
}

138
video_io/sv_camera_def.cpp Normal file
View File

@@ -0,0 +1,138 @@
#include "sv_camera_privately.h"
#include "iostream"
sv_p::CameraBase::CameraBase(int timeOut)
{
this->_timeOut = timeOut;
}
void sv_p::CameraBase::readThread(void)
{
int count = 0;
while (this->cap.isOpened())
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if (this->cap.grab())
{
std::lock_guard<std::mutex> locker(this->frameMutex);
this->cap.retrieve(this->imageBuff);
this->frameEmpty.notify_all();
isGot = true;
// 统计输入的瞬时帧率
this->fpsCurr = 1000.0f / count;
count = 0;
}
else
{
count++;
if (count > this->_timeOut)
{
// 超时则主动关闭相机
this->cap.release();
}
}
}
// 相机断开连接 记录事件后 退出线程
std::cout << "SpireCV (101) Camera has offline, check CAMERA!" << std::endl;
}
bool sv_p::CameraBase::read(cv::Mat &image)
{
bool ret = false;
std::lock_guard<std::mutex> locker(this->frameMutex);
if (this->frameEmpty.wait_for(this->frameMutex, std::chrono::milliseconds(this->_timeOut)) == std::cv_status::no_timeout)
{
// 获取图像
this->imageBuff.copyTo(image);
ret = true;
isGot = false;
}
return ret;
}
bool sv_p::CameraBase::readNoBlock(cv::Mat &image)
{
bool ret = false;
std::lock_guard<std::mutex> locker(this->frameMutex);
if (this->isGot)
{
// 该情况下read()不会阻塞
ret = this->read(image);
}
return ret;
}
#define PARAM_SET_CHECK(param, value) param = (value > 0 ? value : param)
void sv_p::CameraBase::setWH(int width, int height)
{
if (!this->cap.isOpened())
{
PARAM_SET_CHECK(this->_width, width);
PARAM_SET_CHECK(this->_height, height);
}
}
void sv_p::CameraBase::setFps(int fps)
{
PARAM_SET_CHECK(this->_fps, fps);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_FPS, fps);
}
}
void sv_p::CameraBase::setBrightness(float brightness)
{
PARAM_SET_CHECK(this->_brightness, brightness);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_BRIGHTNESS, brightness);
}
}
void sv_p::CameraBase::setContrast(float contrast)
{
PARAM_SET_CHECK(this->_contrast, contrast);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_CONTRAST, contrast);
}
}
void sv_p::CameraBase::setSaturation(float saturation)
{
PARAM_SET_CHECK(this->_saturation, saturation);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_SATURATION, saturation);
}
}
void sv_p::CameraBase::setHue(float hue)
{
PARAM_SET_CHECK(this->_hue, hue);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_HUE, hue);
}
}
void sv_p::CameraBase::setExposure(float exposure)
{
PARAM_SET_CHECK(this->_exposure, exposure);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_EXPOSURE, exposure);
}
}
void sv_p::CameraBase::release(void)
{
if (this->cap.isOpened())
{
this->cap.release();
}
}

View File

@@ -0,0 +1,83 @@
#ifndef __SV_CAMERA_PRIVATELY__
#define __SV_CAMERA_PRIVATELY__
#include "opencv2/opencv.hpp"
#include <stdint.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "sv_camera.h"
namespace sv_p
{
class CameraBase
{
public:
// 图像的属性
int _width = 1280;
int _height = 720;
int _fps = 30;
float _brightness = -1;
float _contrast = -1;
float _saturation = -1;
float _hue = -1;
float _exposure = -1;
int _timeOut;
// 内部状态
float fpsCurr = -1;
bool isGot = false;
// 内部变量
cv::Mat imageBuff;
std::mutex frameMutex;
std::condition_variable_any frameEmpty;
std::thread::native_handle_type readThreadHandle = 0;
cv::VideoCapture cap;
// 获取图像的线程 在这个线程中查询、提取图像
virtual void readThread(void);
// 属性设置的接口
virtual void setWH(int width, int height);
// 基本属性 至少实现1个
virtual bool setStream(const std::string &ip, uint16_t port) { return false; }
virtual bool setName(const std::string &name) { return false; }
virtual bool setIndex(int index) { return false; }
// 扩展属性设置 默认调用opencv的实现
virtual void setFps(int fps);
virtual void setBrightness(float brightness);
virtual void setContrast(float contrast);
virtual void setSaturation(float saturation);
virtual void setHue(float hue);
virtual void setExposure(float exposure);
// 属性获取的接口
virtual sv::CameraType getType(void) { return sv::CameraType::NONE; }
virtual std::string getName(void) { return "\0"; };
virtual bool isActive(void) { return (readThreadHandle == 0 ? false : true); }
int getW(void) { return _width; }
int getH(void) { return _height; }
int getExpectFps(void) { return _fps; }
float getFps(void) { return fpsCurr; }
float getBrightness(void) { return _brightness; }
float getContrast(void) { return _contrast; }
float getSaturation(void) { return _saturation; }
float getHue(void) { return _hue; }
float getExposure(void) { return _exposure; }
// 功能接口函数
virtual bool open(void) = 0;
virtual bool read(cv::Mat &image);
virtual bool readNoBlock(cv::Mat &image);
virtual void release(void);
CameraBase(int timeOut = 500);
~CameraBase();
};
}
#endif

View File

@@ -454,71 +454,6 @@ void drawTargetsInFrame(
}
}
cv::Mat drawTargetsInFrame(
const cv::Mat img_,
const TargetsInFrame& tgts_,
const double scale,
bool with_all,
bool with_category,
bool with_tid,
bool with_seg,
bool with_box
)
{
cv::Mat img_show;
cv::resize(img_, img_show, cv::Size(0, 0), scale, scale);
if (tgts_.rois.size() > 0)
{
cv::Mat image_ret;
cv::addWeighted(img_show, 0.5, cv::Mat::zeros(cv::Size(img_show.cols, img_show.rows), CV_8UC3), 0, 0, image_ret);
cv::Rect roi = cv::Rect((int)(tgts_.rois[0].x1*scale), (int)(tgts_.rois[0].y1*scale), (int)((tgts_.rois[0].x2 - tgts_.rois[0].x1)*scale), (int)((tgts_.rois[0].y2 - tgts_.rois[0].y1)*scale));
img_show(roi).copyTo(image_ret(roi));
image_ret.copyTo(img_show);
}
for (Target tgt : tgts_.targets)
{
cv::circle(img_show, cv::Point(int(tgt.cx * tgts_.width * scale), int(tgt.cy * tgts_.height * scale)), 4, cv::Scalar(0,255,0), 2);
if ((with_all || with_box) && tgt.has_box)
{
Box b;
tgt.getBox(b);
cv::rectangle(img_show, cv::Rect((int)(b.x1 * scale), (int)(b.y1 * scale), (int)((b.x2-b.x1+1)*scale), (int)((b.y2-b.y1+1)*scale)), cv::Scalar(0,0,255), 1, 1, 0);
if ((with_all || with_category) && tgt.has_category)
{
cv::putText(img_show, tgt.category, cv::Point((int)(b.x1*scale), (int)(b.y1*scale)-4), cv::FONT_HERSHEY_DUPLEX, 0.4, cv::Scalar(255,0,0));
}
if ((with_all || with_tid) && tgt.has_tid)
{
char tmp[32];
sprintf(tmp, "TID: %d", tgt.tracked_id);
cv::putText(img_show, tmp, cv::Point((int)(b.x1*scale), (int)(b.y1*scale)-14), cv::FONT_HERSHEY_DUPLEX, 0.4, cv::Scalar(0,0,255));
}
}
if ((with_all || with_seg) && tgt.has_seg)
{
cv::Mat mask = tgt.getMask() * 255;
cv::threshold(mask, mask, 127, 255, cv::THRESH_BINARY);
mask.convertTo(mask, CV_8UC1);
cv::resize(mask, mask, cv::Size(img_show.cols, img_show.rows));
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(mask, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
cv::Mat mask_disp = img_show.clone();
cv::fillPoly(mask_disp, contours, cv::Scalar(255,255,255), cv::LINE_AA);
cv::polylines(img_show, contours, true, cv::Scalar(255,255,255), 2, cv::LINE_AA);
double alpha = 0.6;
cv::addWeighted(img_show, alpha, mask_disp, 1.0-alpha, 0, img_show);
}
}
return img_show;
}
std::string Target::getJsonStr()
{
std::string json_str = "{";
@@ -653,15 +588,6 @@ bool Target::getAruco(int& id, std::vector<cv::Point2f> &corners)
return this->has_aruco;
}
bool Target::getAruco(int& id, std::vector<cv::Point2f> &corners, cv::Vec3d &rvecs, cv::Vec3d &tvecs)
{
id = this->_a_id;
corners = this->_a_corners;
rvecs = this->_a_rvecs;
tvecs = this->_a_tvecs;
return this->has_aruco;
}
bool Target::getBox(Box& b)
{
b = this->_b_box;
@@ -1043,192 +969,172 @@ void VideoWriterBase::releaseImpl()
}
CameraBase::CameraBase(CameraType type, int id)
{
this->_is_running = false;
this->_is_updated = false;
this->_type = type;
// CameraBase::CameraBase(CameraType type, int id)
// {
// this->_is_running = false;
// this->_is_updated = false;
// this->_type = type;
this->_width = -1;
this->_height = -1;
this->_fps = -1;
this->_ip = "192.168.2.64";
this->_port = -1;
this->_brightness = -1;
this->_contrast = -1;
this->_saturation = -1;
this->_hue = -1;
this->_exposure = -1;
this->_fourcc = "MJPG";
// this->_width = -1;
// this->_height = -1;
// this->_fps = -1;
// this->_ip = "192.168.2.64";
// this->_port = -1;
// this->_brightness = -1;
// this->_contrast = -1;
// this->_saturation = -1;
// this->_hue = -1;
// this->_exposure = -1;
this->open(type, id);
}
CameraBase::~CameraBase()
{
this->_is_running = false;
// this->_tt.join();
}
std::string CameraBase::getFourcc()
{
return this->_fourcc;
}
void CameraBase::setFourcc(std::string fourcc)
{
this->_fourcc = fourcc;
}
void CameraBase::setWH(int width, int height)
{
this->_width = width;
this->_height = height;
}
void CameraBase::setFps(int fps)
{
this->_fps = fps;
}
void CameraBase::setIp(std::string ip)
{
this->_ip = ip;
}
void CameraBase::setRtspUrl(std::string rtsp_url)
{
this->_rtsp_url = rtsp_url;
}
void CameraBase::setVideoPath(std::string video_path)
{
this->_video_path = video_path;
}
void CameraBase::setPort(int port)
{
this->_port = port;
}
void CameraBase::setBrightness(double brightness)
{
this->_brightness = brightness;
}
void CameraBase::setContrast(double contrast)
{
this->_contrast = contrast;
}
void CameraBase::setSaturation(double saturation)
{
this->_saturation = saturation;
}
void CameraBase::setHue(double hue)
{
this->_hue = hue;
}
void CameraBase::setExposure(double exposure)
{
this->_exposure = exposure;
}
// this->open(type, id);
// }
// CameraBase::~CameraBase()
// {
// this->_is_running = false;
// // this->_tt.join();
// }
// void CameraBase::setWH(int width, int height)
// {
// this->_width = width;
// this->_height = height;
// }
// void CameraBase::setFps(int fps)
// {
// this->_fps = fps;
// }
// void CameraBase::setIp(std::string ip)
// {
// this->_ip = ip;
// }
// void CameraBase::setPort(int port)
// {
// this->_port = port;
// }
// void CameraBase::setBrightness(double brightness)
// {
// this->_brightness = brightness;
// }
// void CameraBase::setContrast(double contrast)
// {
// this->_contrast = contrast;
// }
// void CameraBase::setSaturation(double saturation)
// {
// this->_saturation = saturation;
// }
// void CameraBase::setHue(double hue)
// {
// this->_hue = hue;
// }
// void CameraBase::setExposure(double exposure)
// {
// this->_exposure = exposure;
// }
int CameraBase::getW()
{
return this->_width;
}
int CameraBase::getH()
{
return this->_height;
}
int CameraBase::getFps()
{
return this->_fps;
}
std::string CameraBase::getIp()
{
return this->_ip;
}
int CameraBase::getPort()
{
return this->_port;
}
double CameraBase::getBrightness()
{
return this->_brightness;
}
double CameraBase::getContrast()
{
return this->_contrast;
}
double CameraBase::getSaturation()
{
return this->_saturation;
}
double CameraBase::getHue()
{
return this->_hue;
}
double CameraBase::getExposure()
{
return this->_exposure;
}
bool CameraBase::isRunning()
{
return this->_is_running;
}
// int CameraBase::getW()
// {
// return this->_width;
// }
// int CameraBase::getH()
// {
// return this->_height;
// }
// int CameraBase::getFps()
// {
// return this->_fps;
// }
// std::string CameraBase::getIp()
// {
// return this->_ip;
// }
// int CameraBase::getPort()
// {
// return this->_port;
// }
// double CameraBase::getBrightness()
// {
// return this->_brightness;
// }
// double CameraBase::getContrast()
// {
// return this->_contrast;
// }
// double CameraBase::getSaturation()
// {
// return this->_saturation;
// }
// double CameraBase::getHue()
// {
// return this->_hue;
// }
// double CameraBase::getExposure()
// {
// return this->_exposure;
// }
// bool CameraBase::isRunning()
// {
// return this->_is_running;
// }
void CameraBase::openImpl()
{
// void CameraBase::openImpl()
// {
}
void CameraBase::open(CameraType type, int id)
{
this->_type = type;
this->_camera_id = id;
// }
// void CameraBase::open(CameraType type, int id)
// {
// this->_type = type;
// this->_camera_id = id;
openImpl();
// openImpl();
if (this->_cap.isOpened())
{
std::cout << "Camera opened!" << std::endl;
this->_is_running = true;
this->_tt = std::thread(&CameraBase::_run, this);
this->_tt.detach();
}
else if (type != CameraType::NONE)
{
std::cout << "Camera can NOT open!" << std::endl;
}
}
void CameraBase::_run()
{
while (this->_is_running && this->_cap.isOpened())
{
if (this->_type != CameraType::VIDEO || this->_is_updated == false)
{
this->_cap >> this->_frame;
this->_is_updated = true;
}
std::this_thread::sleep_for(std::chrono::milliseconds(2));
}
}
bool CameraBase::read(cv::Mat& image)
{
if (this->_type != CameraType::NONE)
{
int n_try = 0;
while (n_try < 5000)
{
if (this->_is_updated)
{
this->_frame.copyTo(image);
this->_is_updated = false;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(20));
n_try ++;
}
}
if (image.cols == 0 || image.rows == 0)
{
throw std::runtime_error("SpireCV (101) Camera cannot OPEN, check CAMERA_ID!");
}
return image.cols > 0 && image.rows > 0;
}
void CameraBase::release()
{
_cap.release();
}
// if (this->_cap.isOpened())
// {
// std::cout << "Camera opened!" << std::endl;
// this->_is_running = true;
// this->_tt = std::thread(&CameraBase::_run, this);
// this->_tt.detach();
// }
// else if (type != CameraType::NONE)
// {
// std::cout << "Camera can NOT open!" << std::endl;
// }
// }
// void CameraBase::_run()
// {
// while (this->_is_running && this->_cap.isOpened())
// {
// this->_cap >> this->_frame;
// this->_is_updated = true;
// std::this_thread::sleep_for(std::chrono::milliseconds(2));
// }
// }
// bool CameraBase::read(cv::Mat& image)
// {
// if (this->_type != CameraType::NONE)
// {
// int n_try = 0;
// while (n_try < 5000)
// {
// if (this->_is_updated)
// {
// this->_is_updated = false;
// this->_frame.copyTo(image);
// break;
// }
// std::this_thread::sleep_for(std::chrono::milliseconds(20));
// n_try ++;
// }
// }
// if (image.cols == 0 || image.rows == 0)
// {
// throw std::runtime_error("SpireCV (101) Camera cannot OPEN, check CAMERA_ID!");
// }
// return image.cols > 0 && image.rows > 0;
// }
// void CameraBase::release()
// {
// _cap.release();
// }

View File

@@ -1,3 +1,4 @@
#if 0
#include "sv_video_input.h"
#include <cmath>
#include <fstream>
@@ -24,11 +25,6 @@ void Camera::openImpl()
{
this->_cap.open(this->_camera_id);
}
if (_fourcc.size() >= 4)
{
const char *fourcc_cstr = _fourcc.c_str();
this->_cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc(fourcc_cstr[0], fourcc_cstr[1], fourcc_cstr[2], fourcc_cstr[3]));
}
if (this->_width > 0 && this->_height > 0)
{
this->_cap.set(cv::CAP_PROP_FRAME_WIDTH, this->_width);
@@ -76,21 +72,14 @@ void Camera::openImpl()
this->_fps = 30;
}
#if defined(PLATFORM_X86_CUDA) || defined(PLATFORM_X86_INTEL)
sprintf(pipe, "rtspsrc location=rtsp://%s:%d/H264?W=%d&H=%d&FPS=%d&BR=4000000 latency=100 ! \
application/x-rtp,media=video ! rtph264depay ! parsebin ! avdec_h264 ! \
videoconvert ! appsink sync=false",
this->_ip.c_str(), this->_port, this->_width, this->_height, this->_fps);
#ifdef PLATFORM_X86_CUDA
sprintf(pipe, "rtsp://%s:%d/H264?W=%d&H=%d&FPS=%d&BR=4000000", this->_ip.c_str(), this->_port, this->_width, this->_height, this->_fps);
this->_cap.open(pipe);
#endif
#ifdef PLATFORM_JETSON
sprintf(pipe, "rtspsrc location=rtsp://%s:%d/H264?W=%d&H=%d&FPS=%d&BR=4000000 latency=100 ! \
application/x-rtp,media=video ! rtph264depay ! parsebin ! nvv4l2decoder enable-max-performancegst=1 ! \
nvvidconv ! video/x-raw,format=(string)BGRx ! videoconvert ! appsink sync=false",
this->_ip.c_str(), this->_port, this->_width, this->_height, this->_fps);
#endif
// printf("%s\r\n",pipe);
sprintf(pipe, "rtspsrc location=rtsp://%s:%d/H264?W=%d&H=%d&FPS=%d&BR=4000000 latency=100 ! application/x-rtp,media=video ! rtph264depay ! parsebin ! nvv4l2decoder enable-max-performancegst=1 ! nvvidconv ! video/x-raw,format=(string)BGRx ! videoconvert ! appsink sync=false", this->_ip.c_str(), this->_port, this->_width, this->_height, this->_fps);
this->_cap.open(pipe, cv::CAP_GSTREAMER);
#endif
}
else if (this->_type == CameraType::GX40)
{
@@ -104,7 +93,7 @@ void Camera::openImpl()
{
this->_port = 554;
}
#if defined(PLATFORM_X86_CUDA) || defined(PLATFORM_X86_INTEL)
#ifdef PLATFORM_X86_CUDA
camera_url << "rtspsrc location = rtsp://user:0000@" << this->_ip << ":" << this->_port
<< "/cam/realmonitor?channel=1&subtype=0 latency=100 ! application/x-rtp,media=video ! \
rtph265depay ! parsebin ! avdec_h265 ! videoscale ! video/x-raw,width=(int)" << this->_width
@@ -136,45 +125,11 @@ void Camera::openImpl()
this->_fps = 30;
}
sprintf(pipe, "nvarguscamerasrc sensor-id=%d ee-mode=0 tnr-mode=0 aeantibanding=0 wbmode=0 ! \
video/x-raw(memory:NVMM), width=(int)%d, height=(int)%d, format=(string)NV12, framerate=(fraction)%d/1 ! \
nvvidconv ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink",
this->_camera_id, this->_width, this->_height, this->_fps);
sprintf(pipe, "nvarguscamerasrc sensor-id=%d ! video/x-raw(memory:NVMM), width=(int)%d, height=(int)%d, format=(string)NV12, framerate=(fraction)%d/1 ! nvvidconv flip-method=0 ! video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink", this->_camera_id, this->_width, this->_height, this->_fps, this->_width, this->_height);
this->_cap.open(pipe, cv::CAP_GSTREAMER);
}
else if (this->_type == CameraType::RTSP)
{
char pipe[512];
if (this->_width <= 0 || this->_height <= 0)
{
this->_width = 1280;
this->_height = 720;
}
if (this->_port <= 0)
{
this->_port = 554;
}
if (this->_fps <= 0)
{
this->_fps = 30;
}
#if defined(PLATFORM_X86_CUDA) || defined(PLATFORM_X86_INTEL)
sprintf(pipe, "rtspsrc location=%s?W=%d&H=%d&FPS=%d latency=100 ! \
application/x-rtp,media=video ! rtph264depay ! parsebin ! avdec_h264 ! \
videoconvert ! appsink sync=false",
this->_rtsp_url.c_str(), this->_width, this->_height, this->_fps);
this->_cap.open(pipe, cv::CAP_GSTREAMER);
#endif
#ifdef PLATFORM_JETSON
sprintf(pipe, "rtspsrc location=%s?W=%d&H=%d&FPS=%d latency=100 ! application/x-rtp,media=video ! rtph264depay ! parsebin ! nvv4l2decoder enable-max-performancegst=1 ! nvvidconv ! video/x-raw,format=(string)BGRx ! videoconvert ! appsink sync=false", this->_rtsp_url.c_str(), this->_width, this->_height, this->_fps);
this->_cap.open(pipe, cv::CAP_GSTREAMER);
#endif
}
else if (this->_type == CameraType::VIDEO)
{
this->_cap.open(this->_video_path);
}
}
}
#endif

View File

@@ -6,13 +6,8 @@
#include "writer_gstreamer_impl.h"
#endif
#ifdef WITH_FFMPEG
#if defined(PLATFORM_X86_CUDA)
#include "x86_cuda/bs_push_streamer.h"
#include "x86_cuda/bs_video_saver.h"
#elif defined(PLATFORM_X86_INTEL)
#include "x86_intel/bs_push_streamer.h"
#include "x86_intel/bs_video_saver.h"
#endif
#include "bs_push_streamer.h"
#include "bs_video_saver.h"
#endif
@@ -42,10 +37,10 @@ bool VideoWriter::setupImpl(std::string file_name_)
return this->_gstreamer_impl->gstreamerSetup(this, file_name_);
#endif
#ifdef WITH_FFMPEG
#if defined(PLATFORM_X86_CUDA)
#ifdef PLATFORM_X86_CUDA
std::string enc = "h264_nvenc";
#elif defined(PLATFORM_X86_INTEL)
std::string enc = "h264_vaapi";
#else
std::string enc = "";
#endif
return this->_ffmpeg_impl->setup(file_path + file_name_ + ".avi", img_sz.width, img_sz.height, (int)fps, enc, 4);
#endif
@@ -110,10 +105,10 @@ bool VideoStreamer::setupImpl()
#endif
#ifdef WITH_FFMPEG
std::string rtsp_url = "rtsp://127.0.0.1/live" + url;
#if defined(PLATFORM_X86_CUDA)
#ifdef PLATFORM_X86_CUDA
std::string enc = "h264_nvenc";
#elif defined(PLATFORM_X86_INTEL)
std::string enc = "h264_vaapi";
#else
std::string enc = "";
#endif
return this->_ffmpeg_impl->setup(rtsp_url, img_sz.width, img_sz.height, 24, enc, bitrate);
#endif