1.问题概括
2.需要注意的点
平均池化如果只有一通道,我们可以把像素值直接相加然后除以像素块大小,最后赋值
但是如果是多通道,要注意:
我们是对他的每一个通道的值进行相加然后再取平均,而不是直接将几个通道的值全部相加。
for (int dy = 0; dy < size; dy++)
{
for (int dx = 0; dx < size; dx++)
{
sum += (double)src.at<Vec3b>(y + dy, x + dx)[c];
}
}
sum /= (double)(size * size);
for (int dy = 0; dy < size; dy++)
{
for (int dx = 0; dx < size; dx++)
{
out.at<Vec3b>(y + dy, x + dx)[c] = (uchar)sum;
}
}
并且对于代码的流程,尤其是使用dx和dy的方式可以注意和记住。
3.实现代码
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
Mat Average_Pooling(Mat src,int size)
{
Mat out = Mat::zeros(src.size(), CV_8UC3);
int channel = src.channels();
double sum = 0;
for (int y = 0; y < src.rows; y += size)
{
for (int x = 0; x < src.cols; x += size)
{
for (int c = 0; c < channel; c++)
{
sum = 0;
for (int dy = 0; dy < size; dy++)
{
for (int dx = 0; dx < size; dx++)
{
sum += (double)src.at<Vec3b>(y + dy, x + dx)[c];
}
}
sum /= (double)(size * size);
for (int dy = 0; dy < size; dy++)
{
for (int dx = 0; dx < size; dx++)
{
out.at<Vec3b>(y + dy, x + dx)[c] = (uchar)sum;
}
}
}
}
}
return out;
}
int main(int argc, char** argv) {
Mat src = imread("t1-10/imori.jpg");
Mat dst = Average_Pooling(src,8);
imshow("dst", dst);
waitKey(0);
return 0;
}
4.代码缺陷
此函数的size必须和图片的像素之间能整除
修改
//这里只写了函数
Mat Average_Pooling(Mat src,int size)
{
Mat out = Mat::zeros(src.size(), CV_8UC3);
int channel = src.channels();
double sum = 0;
int count = 0;
for (int y = 0; y < src.rows; y += size)
{
for (int x = 0; x < src.cols; x += size)
{
for (int c = 0; c < channel; c++)
{
//1.对x和y进行范围修正
/*if (x + size > src.cols)
{
x = src.cols - size;
}
if (y + size > src.rows)
{
y = src.rows - size;
}*/
sum = 0;
//2.直接在条件中进行限定,但是这里值得注意的是,需要自己再定义一个计数变量
//否则最后一组池化由于大小没有8*8但是我们对他进行了8*8的整除,最后结果就是
//最后一行和一列的颜色偏深不正常
for (int dy = 0; dy < size&& y + dy < src.rows; dy++)
{
for (int dx = 0; dx < size&& x + dx < src.cols; dx++)
{
sum += (double)src.at<Vec3b>(y + dy, x + dx)[c];
count++;
}
}
sum /= count;
count = 0;
for (int dy = 0; dy < size && y + dy < src.rows; dy++)
{
for (int dx = 0; dx < size && x + dx < src.cols; dx++)
{
out.at<Vec3b>(y + dy, x + dx)[c] = (uchar)sum;
}
}
}
}
}
return out;
}
没有加count的结果
正常效果