You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

359 lines
9.1 KiB

#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<cv::Rect> &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<AI_PIECE_INFO> 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;
}