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
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;
|
|
}
|