Created
October 18, 2021 12:39
-
-
Save RobertApikyan/c285a339bb10ef7b70ba004329ee96ce to your computer and use it in GitHub Desktop.
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
// | |
// smart_capture.cpp | |
// Runner | |
// | |
// Created by Kim Henneken on 28.04.21. | |
// | |
#include "smart_capture.hpp" | |
#include <opencv2/opencv.hpp> | |
#include <opencv2/imgproc/types_c.h> | |
#include "opencv2/calib3d.hpp" | |
#include "opencv2/highgui.hpp" | |
#include "opencv2/imgproc.hpp" | |
#include "opencv2/features2d.hpp" | |
#include <thread> | |
#include <future> | |
#include <iostream> | |
#include <string> | |
using namespace cv; | |
using namespace std; | |
Mat filter_image(Mat image) | |
{ | |
cvtColor(image, image, COLOR_RGB2GRAY); | |
return image; | |
} | |
ExtractedFeatures extract_features(Mat mask_template, Mat Template, int nfeatures) | |
{ | |
Mat template_filtered = filter_image(Template); | |
Ptr<SIFT> detector = SIFT::create(nfeatures); | |
std::vector<KeyPoint> kp2; | |
Mat des2; | |
detector->detectAndCompute(template_filtered, mask_template, kp2, des2); | |
ExtractedFeatures extractedFeatures; | |
extractedFeatures.des2 = des2; | |
extractedFeatures.kp2 = kp2; | |
return extractedFeatures; | |
} | |
PreparedTemplate prepare_templates(int nfeatures, double ro, Mat MaskTemplate, Mat Template) | |
{ | |
int h = MaskTemplate.size().height; | |
int w = MaskTemplate.size().width; | |
cv::resize(MaskTemplate, MaskTemplate, cv::Size(w * ro, h * ro)); | |
cv::resize(Template, Template, cv::Size(w * ro, h * ro)); | |
Size template_shape = Template.size(); | |
// Mat template_image = Template.setTo(Scalar().all(255.0)); | |
auto future = std::async(extract_features, MaskTemplate, Template, nfeatures); | |
ExtractedFeatures extracted_features = future.get(); | |
PreparedTemplate preparedTemplate; | |
preparedTemplate.template_shape = template_shape; | |
preparedTemplate.des2 = extracted_features.des2; | |
preparedTemplate.kp2 = extracted_features.kp2; | |
preparedTemplate.Template = Template; | |
preparedTemplate.mask_template = MaskTemplate; | |
return preparedTemplate; | |
} | |
StabilisedCard stabilise_card(Mat frame, int min_matches, int nfeatures, std::vector<KeyPoint> kp2, Mat des2, std::vector<int> rect_cords, Size template_shape, String path) | |
{ | |
cv::Rect rect = cv::Rect(rect_cords.at(0), rect_cords.at(2), rect_cords.at(1) - rect_cords.at(0), rect_cords.at(3) - rect_cords.at(2)); | |
Mat img1 = Mat(frame, rect); | |
Mat mask1 = img1.clone().setTo(Scalar().all(255.0)); | |
mask1.convertTo(mask1, CV_8U); | |
double S = mask1.size().height * mask1.size().width; | |
double height = template_shape.height; | |
double width = template_shape.width; | |
double standard = width * height; | |
double H = img1.size().height; | |
double W = img1.size().width; | |
double ratio = pow((S / standard), 0.5); | |
Size sz = Size(W / ratio, H / ratio); | |
cv::resize(img1, img1, sz); | |
cv::resize(mask1, mask1, sz); | |
mask1.setTo(Scalar().all(10)); | |
Mat filtered_img1 = filter_image(img1); | |
// cv::imwrite(path, mask1); | |
Ptr<SIFT> detector = SIFT::create(nfeatures); | |
std::vector<KeyPoint> kp1; | |
Mat des1; | |
detector->detectAndCompute(filtered_img1, noArray(), kp1, des1); | |
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE); | |
std::vector<std::vector<DMatch>> knn_matches; | |
matcher->knnMatch(des1, des2, knn_matches, 2); | |
std::vector<DMatch> good_matches; | |
for (size_t i = 0; i < knn_matches.size(); i++) | |
{ | |
if (knn_matches[i][0].distance < 0.7 * knn_matches[i][1].distance) | |
{ | |
good_matches.push_back(knn_matches[i][0]); | |
} | |
} | |
StabilisedCard stabilisiedCard; | |
if (good_matches.size() > min_matches) | |
{ | |
stabilisiedCard.alignment_quality = (double)good_matches.size() / (double)kp2.size(); | |
return stabilisiedCard; | |
} | |
stabilisiedCard.alignment_quality = 0; | |
return stabilisiedCard; | |
} | |
double SmartCapture::smart_capture(Mat canvas, Mat temp, Mat maskTemplate, String type, String min_matches, String card_nfeatures, String alignment_quality, String ro) | |
{ | |
int min_matches2 = stoi(min_matches); | |
; | |
int card_nfeatures2 = stoi(card_nfeatures); | |
; | |
int template_nfeatures = 5000; | |
double ro2 = atof(ro.c_str()); | |
std::vector<double> rectangle; | |
Mat cap = canvas; | |
// rectangle = {0.15, 0.85, 0.05, 0.95}; | |
// rectangle = {0.075, 0.925, 0.3 / 3, 1.1 / 3}; | |
rectangle = {0.0, 1.0, 0.0, 1.0}; | |
PreparedTemplate Template = prepare_templates(template_nfeatures, ro2, maskTemplate, temp); | |
int h = cap.size().height; | |
int w = cap.size().width; | |
std::vector<int> rect_coords = {(int)round(w * rectangle.at(0)), (int)round(w * rectangle.at(1)), (int)round(h * rectangle.at(2)), (int)round(h * rectangle.at(3))}; | |
// cvtColor( cap, cap, COLOR_RGB2GRAY ); | |
// cap = filter_image(cap); | |
auto future = std::async(stabilise_card, cap, min_matches2, card_nfeatures2, Template.kp2, Template.des2, rect_coords, Template.template_shape, type); | |
StabilisedCard stabilised_card = future.get(); | |
return stabilised_card.alignment_quality; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment