struct savePoint {
public:
int w;
int h;
int x, y, ry;
int area = 0;
float p;
std::string name;
};
float iou(savePoint box1, savePoint box2)
{
int x1 = std::max(box1.x, box2.x);
int y1 = std::max(box1.ry, box2.ry);
int x2 = std::min((box1.x + box1.w), (box2.x + box2.w));
int y2 = std::min((box1.ry + box1.h), (box2.ry + box2.h));
if (x1 > x2 || y1 > y2)
return 0.0f;
float over_area = (x2 - x1) * (y2 - y1);
float iou = over_area / (box1.w * box1.h + box2.w * box2.h - over_area);
return iou;
}
float diou(savePoint box1, savePoint box2)
{
// diou 外接矩形宽、高 计算对角线 距离
int s_top_x = std::min(box1.x, box2.x);
int s_top_y = std::min(box1.y, box2.y);
int s_bot_x = std::max((box1.x + box1.w), (box2.x + box2.w));
int s_bot_y = std::max((box1.ry + box1.h), (box2.ry + box2.h));
int s_w = std::abs(s_bot_x - s_top_x);
int s_h = std::abs(s_bot_y - s_top_y);
int s_c = s_w * s_w + s_h * s_h;
//计算iou
float iou_data = iou(box1, box2);
if (s_c == 0)
return iou_data;
// diou 两个矩形中心点 距离计算
int b1_cx = box1.x + box1.w / 2;
int b1_cy = box1.y + box1.h / 2;
int b2_cx = box2.x + box2.w / 2;
int b2_cy = box2.y + box2.h / 2;
int i_w = std::abs(b1_cx - b2_cx);
int i_h = std::abs(b1_cy - b2_cy);
int i_d = i_w * i_w + i_h * i_h;
//计算diou d^2 / c^2
float u = pow(i_d / s_c, 1);
float dout_term = u;
return iou_data - dout_term;
}
void sort(std::vector<savePoint>&vec_boxs1)
{
for (int i = 0; i < vec_boxs1.size(); i++)
{
for (int j = 0; j < vec_boxs1.size() - i-1; j++)
{
savePoint tmp_boxs;
if (vec_boxs1[j].w*vec_boxs1[j].h < vec_boxs1[j + 1].w*vec_boxs1[j + 1].h)
{
tmp_boxs = vec_boxs1[j];
vec_boxs1[j] = vec_boxs1[j + 1];
vec_boxs1[j + 1] = tmp_boxs;
}
}
}
}
void do_nms(std::vector<savePoint>vec_boxs1,float thresh)
{
sort(vec_boxs1);
for (int i = 0; i < vec_boxs1.size()-1; i++)
{
if (vec_boxs1[i].p == 0) continue;
savePoint a = vec_boxs1[i];
for (int j = i + 1; j < vec_boxs1.size();j++)
{
savePoint b = vec_boxs1[j];
if (iou(a, b) > thresh)
vec_boxs1[j].p = 0;
}
}
for (auto it = vec_boxs1.begin(); it != vec_boxs1.end(); )
{
if ((*it).p == 0)
it = vec_boxs1.erase(it);
else
it++;
}
}
void slide_crop(cv::Mat img, std::vector<cv::Mat> &SubMatPics)
{
int img_w = img.cols;
int img_h = img.rows;
int kernel_width = img_w; //set ROI width
int kernel_heigh = 608; //set ROI height
int overlap_x = 0; //set horizontal overlap
int overlap_y = 58; //set vertical overlap
int strid_x = kernel_width- overlap_x; //set horizontal stride
int strid_y = kernel_heigh- overlap_y; //set vertical stride
int stepx = (img_w - kernel_width)/ strid_x+1; //caculation horizontal steps
int stepy = (img_h - kernel_heigh) / strid_y+1; //caculation vertical steps
int startx, starty; // ROI start point
cv::Mat splitMat = cv::Mat::zeros(kernel_width, kernel_heigh,CV_8UC1);
for (int i = 0; i < stepx; i++)
{
for (int j = 0; j < stepy; j++)
{
startx = i * strid_x;
starty = j * strid_y;
cv::Rect MoveRec = cv::Rect(startx, starty, kernel_width, kernel_heigh);
splitMat = img(MoveRec).clone();
cv::imwrite(std::to_string(j) + ".jpg", splitMat);
SubMatPics.push_back(splitMat); //save ROI image
}
}
}
非极大值抑制及滑动窗口切图
最新推荐文章于 2022-11-19 14:31:50 发布