Opencv 有没有从流中过滤带有瑕疵的图像的方法?
我使用libav和OpenCV将来自RTSP流的一些帧写入磁盘。整个测试代码(基于一些内部代码)如下所示:Opencv 有没有从流中过滤带有瑕疵的图像的方法?,opencv,h.264,rtsp,libavcodec,libav,Opencv,H.264,Rtsp,Libavcodec,Libav,我使用libav和OpenCV将来自RTSP流的一些帧写入磁盘。整个测试代码(基于一些内部代码)如下所示: #include <memory> #include <thread> #include <chrono> #include <cstdlib> #include <sstream> #include <iostream> #include <functional> #include <opencv2
#include <memory>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <functional>
#include <opencv2/opencv.hpp>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
}
using namespace std;
using std::chrono::milliseconds;
using std::this_thread::sleep_until;
using std::chrono::high_resolution_clock;
int main(int argc, const char *argv[]) {
if (argc < 2) {
cerr << "./raw_libav <URI>" << endl;
return 0;
}
constexpr int width = 800, height = 600;
av_register_all();
avcodec_register_all();
avformat_network_init();
av_log_set_level(AV_LOG_VERBOSE);
shared_ptr<void> defer_network_deinit(nhttp://en.cppreference.com/w/cpp/language/move_operatorullptr,
bind(avformat_network_deinit));
auto format_context = avformat_alloc_context();
if (!format_context) {
cerr << 0 << endl;
return 0;
}
shared_ptr<void> defer_free_context(format_context, avformat_free_context);
if (avformat_open_input(&format_context, argv[1], nullptr, nullptr) < 0) {
cerr << 1 << endl;
return 0;
}
if (avformat_find_stream_info(format_context, nullptr) < 0) {
cerr << 2 << endl;
return 0;
}
av_dump_format(format_context, 0, argv[1], false);
AVCodec *codec;
auto stream_id = av_find_best_stream(format_context, AVMEDIA_TYPE_VIDEO, -1,
-1, &codec, 0);
if (stream_id < 0) {
cerr << 3 << endl;
return 0;
}
auto codec_context = format_context->streams[stream_id]->codec;
if (avcodec_open2(codec_context, codec, nullptr) < 0) {
cerr << 4 << endl;
return 0;
}
shared_ptr<void> defer_free_codec_context(codec_context, avcodec_close);
auto sws_context =
sws_getContext(codec_context->width, codec_context->height,
codec_context->pix_fmt, width, height, AV_PIX_FMT_BGR24,
SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
if (!sws_context) {
cerr << 5 << endl;
return 0;
}
shared_ptr<void> defer_free_sws_context(sws_context, sws_freeContext);
auto frame_in = av_frame_alloc();
if (!frame_in) {
cerr << 6 << endl;
return 0;
}
shared_ptr<void> defer_free_frame_in(&frame_in, av_frame_free);
auto frame_out = av_frame_alloc();
if (!frame_out) {
cerr << 7 << endl;
return 0;
}
shared_ptr<void> defer_free_frame_out(&frame_out, av_frame_free);
auto picture = static_cast<uint8_t *>(av_malloc(
sizeof(uint8_t) * avpicture_get_size(AV_PIX_FMT_BGR24, width, height)));
if (!picture) {
cerr << 8 << endl;
return 0;
}
shared_ptr<void> defer_free_picture(picture, av_free);
if (avpicture_fill(reinterpret_cast<AVPicture *>(frame_out), picture,
AV_PIX_FMT_BGR24, width, height) < 0) {
cerr << 9 << endl;
return 0;
}
int result;
string image_dir("capture/");
result = system(("rm -rf " + image_dir).c_str());
result = system(("mkdir -p " + image_dir).c_str());
AVPacket packet;
for (int frame_count = 1;; ++frame_count) {
cout << "Frame " << frame_count << endl;
constexpr int rate = 5;
auto check_point =
high_resolution_clock::now() + milliseconds(1000 / rate);
for (;;) {
if (av_read_frame(format_context, &packet) < 0) {
cerr << 10 << endl;http://en.cppreference.com/w/cpp/language/move_operator
continue;
}
shared_ptr<void> defer_av_free_packet(&packet, av_free_packet);
if (packet.stream_index != stream_id) {
cerr << 11 << endl;
continue;
}
int ready;
if (avcodec_decode_video2(codec_context, frame_in, &ready,
&packet) < 0) {
cerr << 12 << endl;
continue;
}
if (!ready) {
cerr << 13 << endl;
continue;
}
sws_scale(sws_context, frame_in->data, frame_in->linesize, 0,
frame_in->height, frame_out->data, frame_out->linesize);
break;
}
cout << "Writing frame to disk" << endl;
stringstream image_path;
image_path << image_dir << '/' << frame_count << ".png";
auto frame_mat = cv::Mat(height, width, CV_8UC3, frame_out->data[0]);
cv::imwrite(image_path.str(), frame_mat);
sleep_until(check_point);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
外部“C”{
#包括
#包括
#包括
#包括
}
使用名称空间std;
使用std::chrono::毫秒;
使用std::this_线程::sleep_until;
使用std::chrono::高分辨率时钟;
int main(int argc,const char*argv[]{
如果(argc<2){
瑟尔
这可能会将某些或多或少的有效部分误检测为错误,并且某些编解码器可能会返回未初始化/零数据,而不是丢弃帧
codec_context->err_recognition = 0