// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include "opencv2/core.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/imgproc.hpp" #include "clipper.hpp" #include "clipper.cpp" void getcontourarea(float ** box, float unclip_ratio, float & distance){ int pts_num=4; float area = 0.0f; float dist = 0.0f; for (int i=0; i points; for (int j=0; j(i, j); } } return array; } void quickSort(float ** s, int l, int r) { if (l < r) { int i = l, j = r; float x = s[l][0]; float * xp = s[l]; while (i < j) { while(i < j && s[j][0]>= x) j--; if(i < j) std::swap(s[i++], s[j]); while(i < j && s[i][0]< x) i++; if(i < j) std::swap(s[j--], s[i]); } s[i] = xp; quickSort(s, l, i - 1); quickSort(s, i + 1, r); } } void quickSort_vector(std::vector> & box, int l, int r, int axis){ if (l < r){ int i = l, j = r; int x = box[l][axis]; std::vector xp (box[l]); while (i < j) { while(i < j && box[j][axis]>= x) j--; if(i < j) std::swap(box[i++], box[j]); while(i < j && box[i][axis]< x) i++; if(i < j) std::swap(box[j--], box[i]); } box[i] = xp; quickSort_vector(box, l, i - 1, axis); quickSort_vector(box, i + 1, r, axis); } } std::vector> order_points_clockwise(std::vector> pts){ std::vector> box = pts; quickSort_vector(box, 0, int(box.size()-1), 0); std::vector> leftmost = {box[0], box[1]}; std::vector> rightmost = {box[2], box[3]}; if (leftmost[0][1]>leftmost[1][1]) std::swap(leftmost[0], leftmost[1]); if (rightmost[0][1]> rightmost[1][1]) std::swap(rightmost[0], rightmost[1]); std::vector> rect = {leftmost[0], rightmost[0], rightmost[1], leftmost[1]}; return rect; } float ** get_mini_boxes(cv::RotatedRect box, float & ssid){ ssid = box.size.width>=box.size.height?box.size.height:box.size.width; cv::Mat points; cv::boxPoints(box, points); // sorted box points auto array = Mat2Vec(points); quickSort(array, 0, 3); float * idx1=array[0], *idx2=array[1], *idx3=array[2], *idx4=array[3]; if (array[3][1]<=array[2][1]) { idx2 = array[3]; idx3 = array[2]; } else{ idx2 = array[2]; idx3 = array[3]; } if (array[1][1]<=array[0][1]){ idx1 = array[1]; idx4 = array[0]; } else{ idx1 = array[0]; idx4 = array[1]; } array[0] = idx1; array[1] = idx2; array[2] = idx3; array[3] = idx4; return array; } template T clamp(T x, T min, T max) { if (x > max) return max; if (x < min) return min; return x; } float clampf(float x, float min, float max){ if (x > max) return max; if (x < min) return min; return x; } float box_score_fast(float ** box_array, cv::Mat pred){ auto array=box_array; int width = pred.cols; int height = pred.rows; float box_x[4]={array[0][0], array[1][0], array[2][0], array[3][0]}; float box_y[4]={array[0][1], array[1][1], array[2][1], array[3][1]}; int xmin = clamp(int(std::floorf(*(std::min_element(box_x, box_x+4)))), 0, width - 1); int xmax = clamp(int(std::ceilf(*(std::max_element(box_x, box_x+4)))), 0, width - 1); int ymin = clamp(int(std::floorf(*(std::min_element(box_y, box_y+4)))), 0, height - 1); int ymax = clamp(int(std::ceilf(*(std::max_element(box_y, box_y+4)))), 0, height - 1); cv::Mat mask; mask = cv::Mat::zeros(ymax - ymin + 1, xmax - xmin + 1, CV_8UC1); cv::Point root_point[4]; root_point[0] = cv::Point(int(array[0][0])-xmin, int(array[0][1])-ymin); root_point[1] = cv::Point(int(array[1][0])-xmin, int(array[1][1])-ymin); root_point[2] = cv::Point(int(array[2][0])-xmin, int(array[2][1])-ymin); root_point[3] = cv::Point(int(array[3][0])-xmin, int(array[3][1])-ymin); const cv::Point* ppt[1] = {root_point}; int npt[] = {4}; cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(1)); cv::Mat croppedImg; pred(cv::Rect(xmin, ymin, xmax-xmin+1,ymax-ymin+1)).copyTo(croppedImg); auto score = cv::mean(croppedImg, mask)[0]; return score; } std::vector>> boxes_from_bitmap(const cv::Mat pred, const cv::Mat bitmap) { const int min_size=3; const int max_candidates = 1000; const float box_thresh=0.5; int width = bitmap.cols; int height = bitmap.rows; std::vector> contours; std::vector hierarchy; cv::findContours(bitmap, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); int num_contours = contours.size() >= max_candidates ? max_candidates : contours.size(); std::vector>> boxes; for (int _i = 0; _i < num_contours; _i++) { float ssid; cv::RotatedRect box = cv::minAreaRect(contours[_i]); auto array = get_mini_boxes(box, ssid); auto box_for_unclip = array; //end get_mini_box if (ssid< min_size) { continue; } float score; score = box_score_fast(array, pred); //end box_score_fast if (score < box_thresh) continue; // start for unclip cv::RotatedRect points = unclip(box_for_unclip); // end for unclip cv::RotatedRect clipbox = points; auto cliparray = get_mini_boxes(clipbox, ssid); if (ssid < min_size+2) continue; int dest_width=pred.cols; int dest_height=pred.rows; std::vector> intcliparray; for (int num_pt=0; num_pt<4; num_pt++){ std::vector a { int( clampf(roundf(cliparray[num_pt][0]/float(width)*float(dest_width)), 0, float(dest_width)) ), int( clampf(roundf(cliparray[num_pt][1]/float(height)*float(dest_height)), 0, float(dest_height)) )}; intcliparray.push_back(a); } boxes.push_back(intcliparray); }//end for return boxes; } int _max(int a, int b){ return a>=b?a:b; } int _min(int a, int b){ return a>=b?b:a; } std::vector>> filter_tag_det_res(std::vector>> boxes, float ratio_h, float ratio_w, cv::Mat srcimg){ int oriimg_h = srcimg.rows; int oriimg_w = srcimg.cols; std::vector>> root_points; for (int n=0; n img_mean = {0.485, 0.456, 0.406}; std::vector img_std = {0.229, 0.224, 0.225}; float trainData[imgh][imgw*imgc]; while (getline(in, line)) { stringstream ss(line); double x; while (ss >> x) { // trainData[i][j] = float(x) * img_std[j % 3] + img_mean[j % 3]; trainData[i][j] = float(x); j++; } i++; j = 0; } cv::Mat pred_map(imgh, imgw*imgc, CV_32FC1, (float *) trainData); cv::Mat reshape_img = pred_map.reshape(imgc, imgh); return reshape_img; } */ //using namespace std; // //void writetxt(vector> data, std::string save_path){ // // ofstream fout(save_path); // // for (int i = 0; i < data.size(); i++) { // for (int j=0; j< data[0].size(); j++){ // fout << data[i][j] << " "; // } // fout << endl; // } // fout << endl; // fout.close(); //}