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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream>
using namespace cv; using namespace std;
Mat imgOriginal, imgGray, imgBlur, imgCanny, imgThre, imgDil, imgErode, imgWarp, imgCrop; vector<Point> initialPoints,docPoints; float w = 420, h = 596;
Mat preProcessing(Mat img) { cvtColor(img, imgGray, COLOR_BGR2GRAY); GaussianBlur(imgGray, imgBlur, Size(3, 3), 3, 0); Canny(imgBlur, imgCanny, 25, 75); Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); dilate(imgCanny, imgDil, kernel); return imgDil; }
vector<Point> getContours(Mat image) {
vector<vector<Point>> contours; vector<Vec4i> hierarchy;
findContours(image, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); vector<vector<Point>> conPoly(contours.size()); vector<Rect> boundRect(contours.size());
vector<Point> biggest; int maxArea=0;
for (int i = 0; i < contours.size(); i++) { int area = contourArea(contours[i]);
string objectType;
if (area > 1000) { float peri = arcLength(contours[i], true); approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);
if (area > maxArea && conPoly[i].size()==4 ) {
biggest = { conPoly[i][0],conPoly[i][1] ,conPoly[i][2] ,conPoly[i][3] }; maxArea = area; } } } return biggest; }
void drawPoints(vector<Point> points, Scalar color) { for (int i = 0; i < points.size(); i++) { circle(imgOriginal, points[i], 10, color, FILLED); putText(imgOriginal, to_string(i), points[i], FONT_HERSHEY_PLAIN, 4, color, 4); } }
vector<Point> reorder(vector<Point> points) { vector<Point> newPoints; vector<int> sumPoints, subPoints;
for (int i = 0; i < 4; i++) { sumPoints.push_back(points[i].x + points[i].y); subPoints.push_back(points[i].x - points[i].y); }
newPoints.push_back(points[min_element(sumPoints.begin(), sumPoints.end()) - sumPoints.begin()]); newPoints.push_back(points[max_element(subPoints.begin(), subPoints.end()) - subPoints.begin()]); newPoints.push_back(points[min_element(subPoints.begin(), subPoints.end()) - subPoints.begin()]); newPoints.push_back(points[max_element(sumPoints.begin(), sumPoints.end()) - sumPoints.begin()]);
return newPoints; }
Mat getWarp(Mat img, vector<Point> points, float w, float h ) { Point2f src[4] = { points[0],points[1],points[2],points[3] }; Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} };
Mat matrix = getPerspectiveTransform(src, dst); warpPerspective(img, imgWarp, matrix, Point(w, h));
return imgWarp; }
int main() {
string path = "res/paper.jpg"; imgOriginal = imread(path); resize(imgOriginal, imgOriginal, Size(), 0.5, 0.5);
imgThre = preProcessing(imgOriginal);
initialPoints = getContours(imgThre);
docPoints = reorder(initialPoints);
imgWarp = getWarp(imgOriginal, docPoints, w, h);
int cropVal= 5; Rect roi(cropVal, cropVal, w - (2 * cropVal), h - (2 * cropVal)); imgCrop = imgWarp(roi);
imshow("Image", imgOriginal); imshow("Image Dilation", imgThre); imshow("Image Warp", imgWarp); imshow("Image Crop", imgCrop); waitKey(0); }
|