c++ - 我如何像素化一维数组

标签 c++ arrays image image-processing

我想像素化存储在1d数组中的图像,尽管我不确定该怎么做,这是到目前为止我要提出的内容...
像素值目前为3(用于测试)。
目前,它只是沿着图像的左三分之一创建了一部分随机着色的像素,如果我增加了像素化的值,随机着色像素的数量就会减少,反之亦然,那么我在做什么错呢?

我还已经实现了旋转,读取图像和保存新图像,这只是我需要帮助的单独功能。

picture pixelate( const std::string& file_name, picture& tempImage, int& pixelation /* TODO: OTHER PARAMETERS HERE */)
{
picture pixelated = tempImage;
RGB tempPixel;
tempPixel.r = 0;
tempPixel.g = 0;
tempPixel.b = 0;
int counter = 0;
int numtimesrun = 0;

    for (int x = 1; x<tempImage.width; x+=pixelation)
    {
        for (int y = 1; y<tempImage.height; y+=pixelation)
        {
            //RGB tempcol;
            //tempcol for pixelate
            for (int i = 1; i<pixelation; i++)
            {
                for (int j = 1; j<pixelation; j++)
                {
                    tempPixel.r +=tempImage.pixel[counter+pixelation*numtimesrun].colour.r;
                    tempPixel.g +=tempImage.pixel[counter+pixelation*numtimesrun].colour.g;
                    tempPixel.b +=tempImage.pixel[counter+pixelation*numtimesrun].colour.b;
                    counter++;
                    //read colour
                }

            }
            for (int k = 1; k<pixelation; k++)
            {
                for (int l = 1; l<pixelation; l++)
                {
                     pixelated.pixel[numtimesrun].colour.r = tempPixel.r/pixelation;
                     pixelated.pixel[numtimesrun].colour.g = tempPixel.g/pixelation;
                     pixelated.pixel[numtimesrun].colour.b = tempPixel.b/pixelation;
                    //set colour
                }

            }
            counter = 0;
            numtimesrun++;
        }
        cout << x << endl;

    }
    cout << "Image successfully pixelated." << endl;
return pixelated;
}

最佳答案

我不太确定您要如何处理您的代码,但是我可以看到一些问题。

例如,您可以使用for()循环以及从1开始的变量。肯定是错的。 C / C ++中的数组从0开始。

我可以看到的另一个主要问题是pixelation参数。使用它来增加xy而不知道(至少在该函数中)它是否是widthheight的倍数。如果不是这样,您肯定会在右边缘和底部(当然,这些边缘将取决于方向)缺少像素。同样,这很大程度上取决于您要实现的目标。

同样,ij循环从counternumtimesrun定义的位置开始,这意味着要打的最后一行不是tempImage.widthtempImage.height。这样,您很可能会有很多溢出。实际上,这也可以解释您在边缘看到的问题。 (请参见下面的更新)

另一个潜在的问题,如果不看结构声明就无法确定,但是使用tempPixel.c += <value>的总和可能会溢出。如果将RGB分量定义为unsigned char(相当常见),那么您肯定会发生溢出。因此,事实就是这样,您的平均金额就会被打破。如果该结构使用浮点数,那么您就很好。

另请注意,您的平均值是错误的。您正在添加pixelation x pixalation的源数据,并且平均值计算为sum / pixelation。因此,您得到的总和是pixalation倍。您可能想要sum / (pixelation * pixelation)

您使用ij的第一个循环计算总和。数学肯定是错误的。看来,counter + pixelation * numtimesrun表达式将从第二行开始读取。但是,您正在读取i * j值。话虽如此,这可能是您要尝试做的事情(即移动平均线),在这种情况下可以对其进行优化,但我暂时不做介绍。



更新资料

如果我了解您在做什么,表示形式将类似于过滤器。有一张3x3的图片:

.+.         *
+*+    =>
.+.


左边是您正在阅读的内容。这意味着源必须至少为3x3。我在右边显示的是结果。如我们所见,结果需要为1x1。根据我在您的代码中看到的内容,您根本没有考虑到这一点。 (不同的字符代表不同的权重,在您的情况下,所有权重均为1.0)。

您有两种方法可以解决该问题:


生成的图像的大小为width - pixelation * 2 + 1 x height - pixelation * 2 + 1;在这种情况下,您只保留一个结果,而不关心边缘...
您重写代码以处理边缘。这意味着您将使用较少的源数据来计算结果边。另一种方法是计算边缘情况并将其保存在几个输出像素中(即,复制边缘上的像素)。




更新2

嗯...再次查看您的代码,似乎您计算了3x3的平均值并将其保存在3x3中:

.+.         ***
+*+    =>   ***
.+.         ***


然后问题就不同了。 numtimesrun是错误的。在您的kl循环中,您将像素pixelation * pixelation保存为SAME像素,并且每次将像素超前一个。。。因此,您正在执行我在第一次更新中显示的操作,但是您似乎在尝试做我的第二次更新中显示的内容。

每次numtimesrun可以增加pixelation

numtimesrun += pixelation;


但是,这还不足以解决您的kl循环。那里您可能需要计算正确的目的地。可能是这样的(在循环之前还需要重置计数器):

counter = 0;
... for loops ...
    pixelated.pixel[counter+pixelation*numtimesrun].colour.r = ...;
    ... (take care of g and b)
    ++counter;


再一次,我无法确定您要做什么,所以我不知道您为什么要复制相同的像素pixelation x pixelation次。但这解释了为什么只在图像的左侧(或顶部)获得数据(这在很大程度上取决于方向,可以肯定是一侧。如果是1/3,那么pixelation可能是3。)

警告:如果正确实施保存,则如果您不注意前面提到的溢出,将会崩溃。



更新3

如Mark在下面的注释中所解释的,您有一个表示2d图像的数组。在这种情况下,您的counter变量是完全错误的,因为这是100%线性的,而2d图像不是。第二行在更远的地方。此时,您将读取左上角的前3个像素,然后读取同一像素的下3个像素,最后读取仍位于同一行的3个像素。当然,可能是因为这样定义了您的图像,并且这些像素确实是一个接一个的,尽管可能性不大。

Mark的答案很简洁,为您提供了访问正确像素所需的信息。但是,您仍然会被溢出以及widthwidth参数不是height的倍数的事实所困扰...

关于c++ - 我如何像素化一维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27475894/

相关文章:

python - 不重叠某些像素的随机矩形

c++ - 为什么我们需要 [basic.scope.class]/2?

java - 如何检查数组中key的数字是否重复?

arrays - 在 Racket 中,列表是数组吗?

java - 尝试交换第一个和最后一个数组元素的值

image - 具有CMYK颜色的SVG图像-是否可以?

c++ - 在 C++ 中启动进程时隐藏命令提示符

c++ - windows 无法找到 dll,即使它位于 PATH 中的目录中

c++ - 类模板中的虚函数,没有模板类型作为参数/返回值

image - JPEG 图像中的透明背景