[英]C++ Calculating an average of a variable width of numbers in a 2D array
我知道這里已經有類似的問題,但是沒有答案真正對我有幫助。 這是我的問題:
我給了一個512x512像素的數組。 每個像素的值都類似於165.88009。
(稍后我必須在GnuPlot中創建一個熱圖)
現在,我想通過創建可變像素塊(例如4-16)的平均值來“平滑”它,並將其寫入新的2D數組,然后跳到下一個塊,直到完成。
數組的大小應保持不變。 因此,如果我平均4個像素,則這4個像素將獲得新值。
我為此做了一個功能,但無法正常工作。
計算平均值不是我的問題。 問題是我想具有可變的像素寬度,但是我不知道如何使算法跳到下一個塊。
我沒有C ++經驗,也許我必須完全不同。
因此,非常感謝您的幫助或啟發:)
這是我的代碼:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int i, j, m, n, k;
void Average(double **Data, int width) // width gets defined and initiated in main
{
double sum;
double avg;
fstream Output;
Output.open( "GemittelteWerte.dat", ios::out);
double** IV_Matrix = new double* [m];
for (int i=0; i<m; i++)
{
IV_Matrix[i] = new double [n];
}
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
{
IV_Matrix[i][j] = 1.0;
}
}
// Here start all my troubles:
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j+=width)
{
sum = 0.0;
k=j;
for( k; k<(j+width); k++)
{
sum+=Data[i][k];
}
avg=(sum/width);
for (int k; k<(j+width); k++)
{
IV_Matrix[i][k] = avg;
}
}
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
Output<<setprecision(10)<<IV_Matrix[i][j]<<"\t";
}
Output<<"\n";
}
Output.close();
}
//di means diagonal index
for(int di = 0; di < n/width; ++di) {
int sum = 0.0;
//we sum the values
for(int i = di*width; i < (di+1)*width; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
sum += Data[i][j];
}
}
//Divide by the number of values
sum /= width*width;
//Spread the results
for(int i = di*width; i < (di+1)*width; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
IV_Matrix[i][j];
}
}
}
//n might not be a multiple of width
if(n % width != 0) {
//we sum the values
for(int i = (n/width)*width; i < n; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
sum += Data[i][j];
}
}
//Divide by the number of values
sum /= width*width;
//Spread the results
for(int i = (n/width)*width; i < n; ++i)
{
for(int j = (n/width)*width; j < n; ++j)
IV_Matrix[i][j];
}
}
}
該塊是2D塊(4 = 2x2,16 = 4x4)嗎? 您只是想進行2D卷積? 然后最好使用3x3、5x5等內核的奇數寬度。
// int x, y are the dimensions of your image
double get (double **img, int i, int j) // zero padding for areas outside image
{
if (i<0 || i>=x || j<0 || j>=y)
return 0;
else
return img[i][j];
}
void conv (double **img, double **result, int width2) // kernel is (2*width2+1)^2
{
double sum;
for (int i=0; i<x; i++)
for (int j=0; j<y; j++)
{
sum = 0;
for (int ii=-width2; ii<=width2; ii++)
for (int jj=-width2; jj<=width2; jj++)
sum += get(img,i+ii,j+jj) / ((2*width2+1)*(2*width2+1));
result[i][j] = sum;
}
}
這使img平滑化。 然而,它是緩慢而無法分離的解決方案。 對於小圖像和內核,沒有問題。
編輯 :然后更容易:
// x, y are the dimensions of your image (x rows, y colums)
void avg (double **img, double **result, int width) // width must be >= 1 and
{ // should be a divider of y
double sum;
for (int i=0; i<x; i++) // process all rows
{
for (int j=0; j<y; j+=width) // jump in block width through a row
{
sum = 0.0;
for (int w=0; w<width; w++) // calculate average of a block
{
sum += img[i][j+w] / width;
}
for (int b=0; b<width; b++) // write average in each pixel inside block
{
result[i][j+b]= sum;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.