forked from openvinotoolkit/open_model_zoo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request openvinotoolkit#1229 from Wovchena/imgCap
Unify input processing
- Loading branch information
Showing
25 changed files
with
446 additions
and
380 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright (C) 2020 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#pragma once | ||
|
||
#include <gflags/gflags.h> | ||
|
||
#define DEFINE_INPUT_FLAGS \ | ||
DEFINE_string(i, "", input_message); \ | ||
DEFINE_bool(loop, false, loop_message); | ||
|
||
static const char input_message[] = "Required. An input to process. The input must be a single image, a folder of " | ||
"images or anything that cv::VideoCapture can process."; | ||
static const char loop_message[] = "Optional. Enable reading the input in a loop."; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (C) 2020 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include <opencv2/core/mat.hpp> | ||
#include <opencv2/videoio.hpp> | ||
|
||
class ImagesCapture { | ||
public: | ||
const bool loop; | ||
|
||
ImagesCapture(bool loop) : loop{loop} {} | ||
virtual double fps() const = 0; | ||
virtual size_t lastImageId() const = 0; | ||
virtual cv::Mat read() = 0; | ||
virtual ~ImagesCapture() = default; | ||
}; | ||
|
||
// An advanced version of | ||
// try { | ||
// return cv::VideoCapture(std::stoi(input)); | ||
// } catch (const std::invalid_argument&) { | ||
// return cv::VideoCapture(input); | ||
// } catch (const std::out_of_range&) { | ||
// return cv::VideoCapture(input); | ||
// } | ||
std::unique_ptr<ImagesCapture> openImagesCapture(const std::string &input, | ||
bool loop, size_t initialImageId=0, // Non camera options | ||
size_t readLengthLimit=std::numeric_limits<size_t>::max(), // general option | ||
// Camera option: | ||
bool autoFocus=true); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
// Copyright (C) 2020 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#include "samples/images_capture.h" | ||
|
||
#ifdef _WIN32 | ||
#include "w_dirent.hpp" | ||
#else | ||
#include <dirent.h> | ||
#endif | ||
|
||
#include <opencv2/imgcodecs.hpp> | ||
|
||
#include <stdexcept> | ||
#include <string> | ||
#include <memory> | ||
|
||
class InvalidInput {}; | ||
|
||
class ImreadWrapper : public ImagesCapture { | ||
cv::Mat img; | ||
bool canRead; | ||
|
||
public: | ||
ImreadWrapper(const std::string &input, bool loop) : ImagesCapture{loop}, canRead{true} { | ||
img = cv::imread(input); | ||
if(!img.data) throw InvalidInput{}; | ||
} | ||
|
||
double fps() const override {return 0.0;} | ||
|
||
size_t lastImageId() const override {return 0;} | ||
|
||
cv::Mat read() override { | ||
if (loop) return img.clone(); | ||
if (canRead) { | ||
canRead = false; | ||
return img.clone(); | ||
} | ||
return cv::Mat{}; | ||
} | ||
}; | ||
|
||
class DirReader : public ImagesCapture { | ||
std::vector<std::string> names; | ||
size_t fileId; | ||
size_t nextImgId; | ||
const size_t initialImageId; | ||
const size_t readLengthLimit; | ||
const std::string input; | ||
|
||
public: | ||
DirReader(const std::string &input, bool loop, size_t initialImageId, size_t readLengthLimit) : ImagesCapture{loop}, | ||
fileId{0}, nextImgId{0}, initialImageId{initialImageId}, readLengthLimit{readLengthLimit}, input{input} { | ||
DIR *dir = opendir(input.c_str()); | ||
if (!dir) throw InvalidInput{}; | ||
while (struct dirent *ent = readdir(dir)) | ||
if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) | ||
names.emplace_back(ent->d_name); | ||
closedir(dir); | ||
if (names.empty()) throw InvalidInput{}; | ||
sort(names.begin(), names.end()); | ||
size_t readImgs = 0; | ||
while (fileId < names.size()) { | ||
cv::Mat img = cv::imread(input + '/' + names[fileId]); | ||
if (img.data) { | ||
++readImgs; | ||
if (readImgs - 1 >= initialImageId) return; | ||
} | ||
++fileId; | ||
} | ||
throw std::runtime_error{"Can't read the first image from " + input + " dir"}; | ||
} | ||
|
||
double fps() const override {return 0.0;} | ||
|
||
size_t lastImageId() const override {return nextImgId - 1;} | ||
|
||
cv::Mat read() override { | ||
while (fileId < names.size() && nextImgId < readLengthLimit) { | ||
cv::Mat img = cv::imread(input + '/' + names[fileId]); | ||
++fileId; | ||
if (img.data) { | ||
++nextImgId; | ||
return img; | ||
} | ||
} | ||
if (loop) { | ||
fileId = 0; | ||
size_t readImgs = 0; | ||
while (fileId < names.size()) { | ||
cv::Mat img = cv::imread(input + '/' + names[fileId]); | ||
++fileId; | ||
if (img.data) { | ||
++readImgs; | ||
if (readImgs - 1 >= initialImageId) { | ||
nextImgId = 1; | ||
return img; | ||
} | ||
} | ||
} | ||
} | ||
return cv::Mat{}; | ||
} | ||
}; | ||
|
||
class VideoCapWrapper : public ImagesCapture { | ||
cv::VideoCapture cap; | ||
size_t nextImgId; | ||
const double initialImageId; | ||
size_t readLengthLimit; | ||
|
||
public: | ||
VideoCapWrapper(const std::string &input, bool loop, size_t initialImageId, size_t readLengthLimit, bool autoFocus) | ||
: ImagesCapture{loop}, nextImgId{0}, initialImageId{static_cast<double>(initialImageId)} { | ||
try { | ||
cap.open(std::stoi(input)); | ||
this->readLengthLimit = loop ? std::numeric_limits<size_t>::max() : readLengthLimit; | ||
cap.set(cv::CAP_PROP_BUFFERSIZE, 1); | ||
cap.set(cv::CAP_PROP_FRAME_WIDTH, 1280); | ||
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 720); | ||
cap.set(cv::CAP_PROP_AUTOFOCUS, autoFocus); | ||
cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G')); | ||
} catch (const std::invalid_argument&) { | ||
cap.open(input); | ||
this->readLengthLimit = readLengthLimit; | ||
if (!cap.set(cv::CAP_PROP_POS_FRAMES, this->initialImageId)) | ||
throw std::runtime_error{"Can't set the frame to begin with"}; | ||
} catch (const std::out_of_range&) { | ||
cap.open(input); | ||
this->readLengthLimit = readLengthLimit; | ||
if (!cap.set(cv::CAP_PROP_POS_FRAMES, this->initialImageId)) | ||
throw std::runtime_error{"Can't set the frame to begin with"}; | ||
} | ||
if (!cap.isOpened()) throw InvalidInput{}; | ||
} | ||
|
||
double fps() const override {return cap.get(cv::CAP_PROP_FPS);} | ||
|
||
size_t lastImageId() const override {return nextImgId - 1;} | ||
|
||
cv::Mat read() override { | ||
if (nextImgId >= readLengthLimit) { | ||
if (loop && cap.set(cv::CAP_PROP_POS_FRAMES, initialImageId)) { | ||
nextImgId = 1; | ||
cv::Mat img; | ||
cap.read(img); | ||
return img; | ||
} | ||
return cv::Mat{}; | ||
} | ||
cv::Mat img; | ||
if (!cap.read(img) && loop && cap.set(cv::CAP_PROP_POS_FRAMES, initialImageId)) { | ||
nextImgId = 1; | ||
cap.read(img); | ||
} else { | ||
++nextImgId; | ||
} | ||
return img; | ||
} | ||
}; | ||
|
||
std::unique_ptr<ImagesCapture> openImagesCapture(const std::string &input, bool loop, size_t initialImageId, | ||
size_t readLengthLimit, bool autoFocus) { | ||
if (readLengthLimit == 0) throw std::runtime_error{"Read length limit must be positive"}; | ||
try { | ||
return std::unique_ptr<ImagesCapture>(new ImreadWrapper{input, loop}); | ||
} catch (const InvalidInput &) {} | ||
try { | ||
return std::unique_ptr<ImagesCapture>(new DirReader{input, loop, initialImageId, readLengthLimit}); | ||
} catch (const InvalidInput &) {} | ||
try { | ||
return std::unique_ptr<ImagesCapture>(new VideoCapWrapper{input, loop, initialImageId, readLengthLimit, | ||
autoFocus}); | ||
} catch (const InvalidInput &) {} | ||
throw std::runtime_error{"Can't read " + input}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.