opencv做题:平均池化

本文详细介绍了平均池化算法在图像处理中的应用,包括多通道图像处理方式、具体实现代码及注意事项。文中提供了完整的C++代码示例,并针对代码中的缺陷提出了改进方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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的结果
在这里插入图片描述

正常效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值