-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscanner.cpp
More file actions
92 lines (77 loc) · 2.59 KB
/
scanner.cpp
File metadata and controls
92 lines (77 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include<iostream>
#include<vector>
#include<string>
#include<opencv2/opencv.hpp>
void showContours(cv::Mat& img,std::vector<cv::Point> contour);
std::vector<cv::Point> scanner(cv::Mat &img, bool showImg = 1)
{
const int ksize = 5;
const int sampleWidth = 300;
cv::Mat resized;
float ratio = 1.0f;
if(sampleWidth < img.cols)
{
ratio = (float)img.cols/sampleWidth;
cv::resize(img,resized,cv::Size(sampleWidth,img.rows/ratio));
}
else
resized = img;
std::cout<<"downsampled to "<< resized.size()<<" ratio "<<ratio<<"\n";
cv::Mat gray (resized);
cv::cvtColor(resized,gray,cv::COLOR_BGR2GRAY); //handle non bgr type images
cv::medianBlur(gray,gray,ksize);
cv::Mat &canny = gray;
cv::Canny(gray,canny,75,200);
if(showImg)
{
cv::imshow("canny",canny);
cv::waitKey(0);
cv::destroyAllWindows();
}
cv::Mat morphed;
//cv::dilate(canny,dilated,cv::getStructuringElement())
cv::morphologyEx(canny,morphed,cv::MORPH_CLOSE,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(5,5)));
if(showImg)
{
cv::imshow("morphed",morphed);
cv::waitKey(0);
cv::destroyAllWindows();
}
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Point> finalContour;
finalContour.reserve(4);
cv::findContours(morphed,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);
sort(contours.begin(), contours.end(), [](const std::vector<cv::Point>& c1, const std::vector<cv::Point>& c2){
return cv::contourArea(c1, false) > cv::contourArea(c2, false);});
for(int i = 0; i !=contours.size(); ++i)
{
double perimeter = cv::arcLength(contours[i],true);
std::vector<cv::Point> approx;
cv::approxPolyDP(contours[i],approx,0.02*perimeter,true);
if(approx.size() == 4)
{
finalContour = approx;
break;
}
}
std::cout<<contours.size()<<" contours\n";
// std::cout<<"downsampled contour"<<finalContour<<"\n";
if(showImg) showContours(resized,finalContour);
for(cv::Point &point : finalContour)
{
point.x *= 3.2f;
point.y *= 3.2f;
}
// std::cout<<"original contour"<<finalContour<<"\n";
return finalContour;
}
void showContours(cv::Mat& img,std::vector<cv::Point> contour)
{
std::vector<std::vector<cv::Point>> tempContours;
tempContours.push_back(contour);
cv::Mat temp = img.clone();
cv::drawContours(temp,tempContours,-1,cv::Scalar(0,0,255));
cv::imshow("image",temp);
cv::waitKey(0);
cv::destroyAllWindows();
}