یکی از روش های خیلی ساده استفاده از مومنت است که به راحتی با مومنت مرتبه اول و دوم مرکز و ابعاد تصویر را بدست میارم و سپس با توجه به این پارامترها به صورت زیر عملیات نرمال سازی انجام میشه.
void getCentralMoment(cv::Mat src, cv::Point ¢er, cv::Size &sigma, int a = 4) {
Moments mm = moments(src, true);
center = cv::Point(int(mm.m10 / mm.m00), int(mm.m01 / mm.m00));
sigma = cv::Size(int(a * sqrt(mm.mu20 / mm.m00)), int(a * sqrt(mm.mu02 / mm.m00)));
}
void normImageByMoments(cv::InputArray _src, cv::InputOutputArray& _dst, int norm_dim) {
cv::Mat src = _src.getMat();
cv::Point center;
cv::Size sigma;
getCentralMoment(src, center, sigma);
const cv::Size sigma2 = cv::Size(sigma.width / 2, sigma.height / 2);
const cv::Size norm_size(norm_dim, norm_dim);
const float container_scale = 1.42f;
const int container_dim = int(norm_dim * container_scale);
const cv::Size container_size(container_dim, container_dim);
const int inner_dis = (container_dim - norm_dim) / 2;
cv::Point center_p(norm_size.width / 2, norm_size.height / 2);
float scale_x = (float)norm_size.width / sigma.width;
float scale_y = (float)norm_size.height / sigma.height;
cv::Mat container_mat(cv::Size(container_dim, container_dim), CV_8UC1, cv::Scalar::all(0));
std::vector<cv::Point> src_points;
src_points.push_back(cv::Point(center.x - sigma2.width, center.y - sigma2.height));
src_points.push_back(cv::Point(center.x + sigma2.width, center.y - sigma2.height));
src_points.push_back(cv::Point(center.x + sigma2.width, center.y + sigma2.height));
src_points.push_back(cv::Point(center.x - sigma2.width, center.y + sigma2.height));
std::vector<cv::Point> dst_points;
for (int i = 0; i < src_points.size(); i++) {
cv::Point norm_pnt;
norm_pnt.y = int(scale_y * (src_points[i].y - center.y) + center_p.y + inner_dis);
norm_pnt.x = int(scale_x * (src_points[i].x - center.x) + center_p.x + inner_dis);
dst_points.push_back(norm_pnt);
}
cv::Rect src_rect = cv::boundingRect(src_points);
cv::Rect dst_rect = cv::boundingRect(dst_points);
cv::resize(src(src_rect), container_mat(dst_rect), dst_rect.size(), 0, 0, CV_INTER_NN);
cv::Point lt(container_dim / 2 - (norm_dim / 2 - ((norm_dim + 1) % 2)), container_dim / 2 - (norm_dim / 2 - ((norm_dim + 1) % 2)));
cv::Rect norm_region(lt, norm_size);
container_mat(norm_region).copyTo(_dst);
}