#include "AIClassify.h" #include "AICommonDefine.h" bool compare_Piece(const AI_PIECE_INFO &a, const AI_PIECE_INFO &b) { return a.abs_L < b.abs_L; } AIClassify::AIClassify() { } AIClassify::~AIClassify() { } cv::Rect AIClassify::GetCutRoi(cv::Rect roi, const cv::Mat &img, int nwidth, int nheight) { cv::Rect cutroi; int pc_x = roi.x + roi.width * 0.5; int pc_y = roi.y + roi.height * 0.5; bool bresize = false; if (roi.width < nwidth && roi.height < nheight) { cutroi.width = nwidth; cutroi.x = pc_x - nwidth * 0.5; cutroi.height = nheight; cutroi.y = pc_y - nheight * 0.5; } else { // 宽 高 if (roi.width > roi.height) { cutroi.width = roi.width + 20; cutroi.x = roi.x - 10; float fsx = nheight * 1.0f / nwidth; cutroi.height = cutroi.width * fsx; cutroi.y = pc_y - cutroi.height * 0.5; } else { cutroi.height = roi.height + 20; cutroi.y = roi.y - 10; float fsy = nwidth * 1.0f / nheight; cutroi.width = cutroi.height * fsy; cutroi.x = pc_x - cutroi.width * 0.5; } bresize = true; } if (cutroi.x < 0) { cutroi.x = 0; } if (cutroi.y < 0) { cutroi.y = 0; } if (cutroi.x + cutroi.width >= img.cols) { cutroi.x = img.cols - cutroi.width; if (cutroi.x < 0) { cutroi.x = 0; if (cutroi.x + cutroi.width >= img.cols) { cutroi.width = img.cols; } } } if (cutroi.y + cutroi.height >= img.rows) { cutroi.y = img.rows - cutroi.height; if (cutroi.y < 0) { cutroi.y = 0; if (cutroi.y + cutroi.height >= img.rows) { cutroi.height = img.rows; } } } return cutroi; } int AIClassify::GetDetRoiList(const cv::Mat &src_Img, cv::Rect qx_roi, std::vector &samllRoiList, int nwidth, int nheight) { // qx_roi.x = 10; // qx_roi.y = src_Img.rows - 10; // qx_roi.width = src_Img.rows - 150; // qx_roi.height = 8; int Min_SizeWH = 160; int Max_sizeWH = 400; // 块之间重叠度 int overlap = 100; // 单边的块数最多 int Edge_Piece_single_Num = 7; // 总的块数最多支持 9个。 int Edge_Piece_Sum_Num = 9; int qx_w = qx_roi.width; int qx_h = qx_roi.height; // 长边、短边 int long_side = qx_w; int short_side = qx_h; if (qx_w >= qx_h) { long_side = qx_w; short_side = qx_h; } else { long_side = qx_h; short_side = qx_w; } // printf("img %d %d qx %d %d \n", src_Img.cols, src_Img.rows, long_side, short_side); std::vector pieceList; if (long_side <= Min_SizeWH) { AI_PIECE_INFO tem; tem.len = long_side; tem.num = 1; tem.long_num = 1; tem.short_num = 1; tem.abs_L = 0; pieceList.push_back(tem); } else { // 1、从长边开始计算 for (int i = 1; i <= Edge_Piece_single_Num; i++) { int piece_len = std::ceil(long_side * 1.0f / i); int piece_overlap_len = std::ceil(piece_len + (i - 1) / i * overlap); int long_Piece_Num = i; int short_Piece_Num = std::ceil(short_side * 1.0f / piece_overlap_len); int sum_Piece_Num = long_Piece_Num * short_Piece_Num; // printf("piece size %d %d long Num %d short Num %d sum %d \n", piece_len, piece_overlap_len, long_Piece_Num, short_Piece_Num, sum_Piece_Num); if (sum_Piece_Num > Edge_Piece_Sum_Num) { continue; } AI_PIECE_INFO tem; tem.len = piece_overlap_len; tem.num = sum_Piece_Num; tem.long_num = long_Piece_Num; tem.short_num = short_Piece_Num; tem.abs_L = std::abs(piece_overlap_len - Max_sizeWH); pieceList.push_back(tem); } } std::sort(pieceList.begin(), pieceList.end(), compare_Piece); // for (int i = 0; i < pieceList.size(); i++) // { // pieceList.at(i).print(std::to_string(i)); // } if (pieceList.size() <= 0) { // printf("Select Roi fail\n"); return 1; } AI_PIECE_INFO selectPiece; selectPiece.len = pieceList.at(0).len; selectPiece.num = pieceList.at(0).num; selectPiece.long_num = pieceList.at(0).long_num; selectPiece.short_num = pieceList.at(0).short_num; selectPiece.abs_L = pieceList.at(0).abs_L; // selectPiece.print("select"); int W_Piece_Num = selectPiece.long_num; int H_Piece_Num = selectPiece.short_num; if (qx_w >= qx_h) { W_Piece_Num = selectPiece.long_num; H_Piece_Num = selectPiece.short_num; } else { W_Piece_Num = selectPiece.short_num; H_Piece_Num = selectPiece.long_num; } int Piece_len = selectPiece.len; if (Piece_len < Min_SizeWH) { Piece_len = Min_SizeWH; } /////////////////、计算宽度方向 块的个数 和 重叠 /////////////////////// // 块的个数 int nBlocknum_x = W_Piece_Num; int use_MinOverlap_Width = 0; // 计算重叠率 if (nBlocknum_x > 1) { // 有多个块,要判断 块的重叠是否满足要求 int nSumLen_x = nBlocknum_x * Piece_len; // float fOverlap_x = (nSumLen_x - qx_w) * 1.0f / (nBlocknum_x - 1); use_MinOverlap_Width = int(fOverlap_x); } /////////////////、计算高度方向 块的个数 和 重叠 /////////////////////// // 块的个数 int nBlocknum_y = H_Piece_Num; int use_MinOverlap_Height = 0; // 计算重叠率 if (nBlocknum_y > 1) { // 有多个块,要判断 块的重叠是否满足要求 int nSumLen_y = nBlocknum_y * Piece_len; // float fOverlap_y = (nSumLen_y - qx_h) * 1.0f / (nBlocknum_y - 1); use_MinOverlap_Height = int(fOverlap_y); } int start_x = qx_roi.x; int start_y = qx_roi.y; int end_x = qx_roi.width + qx_roi.x; int end_y = qx_roi.height + qx_roi.y; // 有效图片 宽 高 int det_width = qx_roi.width; int det_height = qx_roi.height; int AI_Img_width = Piece_len; int AI_Img_height = Piece_len; if (nBlocknum_x == 1) { int sx = AI_Img_width - det_width; int sub_x = 0; if (sx > 0) { sub_x = sx / 2; } start_x -= sub_x; if (start_x < 0) { start_x = 0; } } int cut_sy = qx_roi.y; int cut_ey = qx_roi.y + Piece_len; if (nBlocknum_y == 1) { int sy = AI_Img_width - det_height; int sub_y = 0; if (sy > 0) { sub_y = sy / 2; } start_y -= sub_y; if (start_y < 0) { start_y = 0; } } cut_sy = start_y; cut_ey = start_y + AI_Img_height; if (cut_ey >= src_Img.rows) { cut_ey = src_Img.rows; cut_sy = cut_ey - AI_Img_height; } for (int iy = 0; iy < nBlocknum_y; iy++) { int nleny = end_y - cut_ey; int cut_sx = start_x; int cut_ex = start_x + AI_Img_width; if (cut_ex >= src_Img.cols) { cut_ex = src_Img.cols; cut_sx = cut_ex - AI_Img_width; } for (int ix = 0; ix < nBlocknum_x; ix++) { cv::Rect roi; roi.x = cut_sx; roi.y = cut_sy; roi.width = AI_Img_width; roi.height = AI_Img_height; samllRoiList.push_back(roi); // 剩余长度 int nlenx = end_x - cut_ex; if (nlenx > AI_Img_width) { cut_sx = cut_sx + AI_Img_width - use_MinOverlap_Width; cut_ex = cut_sx + AI_Img_width; } else { cut_sx = end_x - AI_Img_width; cut_ex = cut_sx + AI_Img_width; } } if (nleny > AI_Img_height) { cut_sy = cut_sy + AI_Img_height - use_MinOverlap_Height; cut_ey = cut_sy + AI_Img_height; } else { cut_sy = end_y - AI_Img_height; cut_ey = cut_sy + AI_Img_height; } } // 如果是偶数个,则需要再加个一个。 int sumblob = nBlocknum_y * nBlocknum_x; if (sumblob % 2 == 0) { cv::Rect temRoi = GetCutRoi(qx_roi, src_Img, nwidth, nheight); samllRoiList.push_back(temRoi); } if (false) { cv::Mat showimg = src_Img.clone(); if (showimg.channels() == 1) { cv::cvtColor(showimg, showimg, cv::COLOR_GRAY2BGR); } cv::rectangle(showimg, qx_roi, cv::Scalar(255, 255, 0), 5); for (size_t i = 0; i < samllRoiList.size(); i++) { cv::rectangle(showimg, samllRoiList.at(i), cv::Scalar(255, 0, 0)); } static int idx = 0; cv::imwrite(std::to_string(idx++) + "tem_piece.png", showimg); } // getchar(); return 0; }