【问题标题】:C++ Calculating an average of a variable width of numbers in a 2D arrayC ++计算二维数组中可变宽度数字的平均值
【发布时间】:2013-12-08 18:27:47
【问题描述】:

我知道这里已经有类似的问题,但没有任何答案对我有帮助。 这是我的问题:
我给出了一个包含 512x512 像素的数组。每个像素都有一个类似 165.88009 的值。
(稍后我必须在 GnuPlot 中创建热图)

现在我想通过创建可变像素块(如 4-16)的平均值来“平滑”它,并将其写入新的二维数组并跳转到下一个块,直到完成。
数组的大小应该保持不变。因此,如果我平均 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();
}

【问题讨论】:

    标签: c++ arrays average


    【解决方案1】:

    这个块是 2D 块(4 = 2x2,16 = 4x4)吗?你只是想做一个二维卷积?然后最好使用 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;
                    }
            }
    }
    

    【讨论】:

    • 不,它不是 2D 块。我只想要连续 4-16 个像素的平均值。所以我得到平均值,比如说 4 个像素,将其写入一个新矩阵或覆盖旧的 4 个像素,然后转到下一个 4 个像素。
    • 现在工作正常。谢谢!
    【解决方案2】:
    //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];
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 1970-01-01
      相关资源
      最近更新 更多