-
Notifications
You must be signed in to change notification settings - Fork 1
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 #11 from rursprung/implement-first-version-of-apps
implement first version of the apps + change API to be a class
- Loading branch information
Showing
7 changed files
with
202 additions
and
46 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
add_executable(banana-app-live main.cpp) | ||
|
||
target_link_libraries(banana-app-static PRIVATE banana-lib) | ||
target_link_libraries(banana-app-live | ||
PRIVATE banana-lib | ||
) |
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 |
---|---|---|
@@ -1,7 +1,66 @@ | ||
#include <iostream> | ||
#include <filesystem> | ||
#include <stdexcept> | ||
#include <format> | ||
|
||
int main() { | ||
// TODO: implement live camera feed | ||
std::cerr << "not yet implemented!" << std::endl; | ||
return 1; | ||
#include <opencv2/opencv.hpp> | ||
|
||
#include <banana-lib/lib.hpp> | ||
|
||
const cv::Size kWindowSize = {768, 512}; | ||
|
||
[[nodiscard]] | ||
auto GetVideoCaptureFromArgs(int const argc, char const * const argv[]) -> cv::VideoCapture { | ||
if(argc > 2) { | ||
throw std::runtime_error(std::format("expected 0 or 1 arguments but got {}!", argc-1)); | ||
} else if(argc == 2) { | ||
try { | ||
// numeric value => it's the index of a video device | ||
return cv::VideoCapture{std::stoi(argv[1])}; | ||
} catch (std::invalid_argument const& ex) { | ||
// non-numeric value => treat it as a path, url or similar and let OpenCV check if it's valid | ||
return cv::VideoCapture{argv[1]}; | ||
} | ||
} else { // argc == 1 | ||
return cv::VideoCapture{0}; | ||
} | ||
} | ||
|
||
void ShowAnalysisResult(banana::AnnotatedAnalysisResult const& analysis_result) { | ||
std::string const windowName = "analysis result | press q to quit"; | ||
cv::namedWindow(windowName, cv::WINDOW_KEEPRATIO); | ||
cv::imshow(windowName, analysis_result.annotated_image); | ||
cv::resizeWindow(windowName, kWindowSize); | ||
} | ||
|
||
int main(int const argc, char const * const argv[]) { | ||
banana::Analyzer const analyzer{}; | ||
try { | ||
auto cap = GetVideoCaptureFromArgs(argc, argv); | ||
if(!cap.isOpened()) { | ||
std::cerr << "can't use camera" << std::endl; | ||
return 1; | ||
} | ||
|
||
while (true) { | ||
cv::Mat frame; | ||
cap >> frame; | ||
auto const analysisResult = analyzer.AnalyzeAndAnnotateImage(frame); | ||
|
||
if (analysisResult) { | ||
ShowAnalysisResult(analysisResult.value()); | ||
} else { | ||
std::cerr << "failed to analyse the image: " << analysisResult.error().ToString() << std::endl; | ||
return 1; | ||
} | ||
|
||
if (cv::pollKey() == 'q') { | ||
return 0; | ||
} | ||
} | ||
} catch (std::exception const& ex) { | ||
std::cerr << ex.what() << std::endl; | ||
std::cerr << "Usage: " << argv[0] << " [capture_device_id|video_path]" << std::endl; | ||
return 1; | ||
} | ||
} |
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 |
---|---|---|
@@ -1,3 +1,5 @@ | ||
add_executable(banana-app-static main.cpp) | ||
|
||
target_link_libraries(banana-app-static PRIVATE banana-lib) | ||
target_link_libraries(banana-app-static | ||
PRIVATE banana-lib | ||
) |
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 |
---|---|---|
@@ -1,7 +1,55 @@ | ||
#include <iostream> | ||
#include <filesystem> | ||
#include <stdexcept> | ||
#include <format> | ||
|
||
int main() { | ||
// TODO: implement static image feed (either single pictures and/or a saved video) | ||
std::cerr << "not yet implemented!" << std::endl; | ||
return 1; | ||
#include <opencv2/opencv.hpp> | ||
|
||
#include <banana-lib/lib.hpp> | ||
|
||
const cv::Size kWindowSize = {768, 512}; | ||
|
||
[[nodiscard]] | ||
auto GetPathFromArgs(int const argc, char const * const argv[]) -> std::filesystem::path { | ||
if(argc != 2) { | ||
throw std::runtime_error(std::format("expected 1 argument but got {}!", argc-1)); | ||
} | ||
|
||
auto const image_path = std::filesystem::path(argv[1]); | ||
if (!std::filesystem::exists(image_path)) { | ||
throw std::runtime_error(std::format("specified path does not exist: {}", image_path.string())); | ||
} | ||
|
||
return image_path; | ||
} | ||
|
||
void ShowAnalysisResult(banana::AnnotatedAnalysisResult const& analysis_result) { | ||
std::string const windowName = "analysis result | press q to quit"; | ||
cv::namedWindow(windowName, cv::WINDOW_KEEPRATIO); | ||
cv::imshow(windowName, analysis_result.annotated_image); | ||
cv::resizeWindow(windowName, kWindowSize); | ||
cv::waitKey(); | ||
} | ||
|
||
int main(int const argc, char const * const argv[]) { | ||
banana::Analyzer const analyzer{}; | ||
try { | ||
auto const path = GetPathFromArgs(argc, argv); | ||
auto const img = cv::imread(path.string()); | ||
|
||
auto const analysisResult = analyzer.AnalyzeAndAnnotateImage(img); | ||
|
||
if(analysisResult) { | ||
ShowAnalysisResult(analysisResult.value()); | ||
} else { | ||
std::cerr << "failed to analyse the image: " << analysisResult.error().ToString() << std::endl; | ||
return 1; | ||
} | ||
} catch (std::exception const& ex) { | ||
std::cerr << ex.what() << std::endl; | ||
std::cerr << "Usage: " << argv[0] << " [image_path]" << std::endl; | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} |
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 |
---|---|---|
@@ -1,33 +1,38 @@ | ||
#include <stdexcept> | ||
|
||
#include <banana-lib/lib.hpp> | ||
|
||
namespace banana { | ||
|
||
auto AnalyzeImage(cv::Mat const& image) -> std::expected<std::list<AnalysisResult>, AnalysisError> { | ||
auto Analyzer::AnalyzeImage(cv::Mat const& image) const -> std::expected<std::list<AnalysisResult>, AnalysisError> { | ||
return std::unexpected(AnalysisError::kNotYetImplementedError); | ||
} | ||
|
||
/** | ||
* Annotate an image with the result from a previous analysis (the analysis must come from the same image). | ||
* This is meant for visualisation to users and is not guaranteed to produce stable results. | ||
* | ||
* @param image a previously analysed image | ||
* @param analysis_result the result of the previous analysis (done using AnalyzeImage). | ||
* @return a copy of the original image with annotations. | ||
* @see AnalyzeImage | ||
*/ | ||
[[nodiscard]] | ||
auto AnnotateImage(cv::Mat const& image, std::list<AnalysisResult> const& analysis_result) -> cv::Mat { | ||
auto Analyzer::AnnotateImage(cv::Mat const& image, std::list<AnalysisResult> const& analysis_result) const -> cv::Mat { | ||
auto annotated_image = cv::Mat{image}; | ||
|
||
// TODO: use analysis_result to annotate the image | ||
|
||
return annotated_image; | ||
} | ||
|
||
auto AnalyzeAndAnnotateImage(cv::Mat const& image) -> std::expected<AnnotatedAnalysisResult, AnalysisError> { | ||
return AnalyzeImage(image) | ||
.and_then([&image](std::list<AnalysisResult> const& analysis_result) -> std::expected<AnnotatedAnalysisResult, AnalysisError> { | ||
return AnnotatedAnalysisResult{AnnotateImage(image, analysis_result), analysis_result}; | ||
auto Analyzer::AnalyzeAndAnnotateImage(cv::Mat const& image) const -> std::expected<AnnotatedAnalysisResult, AnalysisError> { | ||
return this->AnalyzeImage(image) | ||
.and_then([&image, this](std::list<AnalysisResult> const& analysis_result) -> std::expected<AnnotatedAnalysisResult, AnalysisError> { | ||
return AnnotatedAnalysisResult{this->AnnotateImage(image, analysis_result), analysis_result}; | ||
}); | ||
} | ||
|
||
auto AnalysisError::ToString() const -> std::string { | ||
switch(value) { | ||
case kNotYetImplementedError: | ||
return "not yet implemented!"; | ||
default: | ||
throw std::runtime_error("unknown AnalysisError type!"); | ||
} | ||
} | ||
|
||
AnalysisError::operator std::string() const { | ||
return this->ToString(); | ||
} | ||
} |