将图片按照固定大小网格分割,网格内的像素值取网格内所有像素的平均值。我们将这种把图片使用均等大小网格分割,并求网格内代表值的操作称为池化(Pooling)。池化操作是卷积神经网络(Convolutional Neural Network)中重要的图像处理方式。平均池化按照下式定义:
v = 1/|R| * Sum_{i in R} v_i
请把大小为 128×128 的imori.jpg
使用 8×8 的网格做平均池化。
python实现:
import cv2
import numpy as np
# Read image
img = cv2.imread("imori.jpg")
# Average Pooling
out = img.copy()
H, W, C = img.shape
G = 8
Nh = int(H / G)
Nw = int(W / G)
for y in range(Nh):
for x in range(Nw):
for c in range(C):
out[G*y:G*(y+1), G*x:G*(x+1), c] = np.mean(out[G*y:G*(y+1), G*x:G*(x+1), c]).astype(np.int)
# Save result
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
C++实现:
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <math.h>
int main(int argc, const char* argv[]){
cv::Mat img = cv::imread("imori.jpg", cv::IMREAD_COLOR);
int width = img.rows;
int height = img.cols;
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);
int r = 8;
double v = 0;
for (int j = 0; j < height; j+=r){
for (int i = 0; i < width; i+=r){
for (int c = 0; c < 3; c++){
v = 0;
for (int _j = 0; _j < r; _j++){
for (int _i = 0; _i < r; _i++){
v += (double)img.at<cv::Vec3b>(j+_j, i+_i)[c];
}
}
v /= (r * r);
for (int _j = 0; _j < r; _j++){
for (int _i = 0; _i < r; _i++){
out.at<cv::Vec3b>(j+_j, i+_i)[c] = (uchar)v;
}
}
}
}
}
//cv::imwrite("out.jpg", out);
cv::imshow("answer", out);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
输入:
输出: