0

所以我有一张我想用棋盘图案覆盖的图像。到目前为止,这是我想出的:

for ( uint_8 nRow = 0; nRow < image.width(); ++nRow)
        for (uint_8 nCol = 0; nCol < image.height(); ++nCol)
                  if(((nRow/20 + nCol/20) % 2) == 0)
                        memset(&image.data[nCol + nRow], 0, 1);

不幸的是产生了一个白色的图像。我不认为这是非常高效的,因为memset图像中的每个像素而不是多个像素都被调用。为什么这段代码不产生棋盘图案?你会如何改进它?

4

2 回答 2

2

为了获得更好的性能,不要将图像视为二维实体。相反,将其视为连续数据的一维数组,其中图像的所有行一个接一个地排列。

使用这种方法,您可以使用单个循环一次性编写模式,在每次迭代中,您 memset() 多个相邻像素并将索引增加您设置的像素数量的两倍:

int data_size = image.width() * image.height();
for (auto it = image.data; it < image.data + data_size; it += 20) {
    memset(it, 0, 20);
    if (((it - data) + 40) % (20 * 400) == 0) {
        it += 40;
    } else if (((it - data) + 20) % (20 * 400) != 0) {
        it += 20;
    }
}

(如果您不使用 C++11,请替换auto为 的类型;我怀疑它是.)image.dataunsigned char*

这对 CPU 缓存预取非常友好。它对编译器也很友好,它可以潜在地矢量化和/或执行循环展开。

于 2013-08-07T12:18:53.333 回答
0

如果您的图像尺寸是棋盘格大小的倍数:(我用 C 编码,但转置为 C++ 相当容易)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define uint unsigned int
#define WIDTH  40
#define HEIGHT 40
#define BLOCK_SIZE 5

void create_checker_row(uint* row, uint size_block, uint nb_col, uint offset )
{
    uint ic;
    for (ic = size_block*offset ; ic < nb_col; ic+= 2*size_block )
    {
        memset( (row + ic) , 0, size_block*sizeof(uint) );
    }
}

int main()
{
    uint ir,ic;

    // image creation
    uint* pixels = (uint*) malloc(WIDTH*HEIGHT*sizeof(uint));
    for (ir = 0; ir < WIDTH; ir++)
    {
        for ( ic = 0; ic < HEIGHT; ic++)
        {
            // arbitrary numbers
            pixels[ir*WIDTH + ic] = (ir*WIDTH + ic) % 57 ;
            printf("%d,", pixels[ir*WIDTH + ic] );
        }
        printf("\n");
    } 

    for (ir = 0; ir < WIDTH; ir++)
    {
        create_checker_row( pixels + ir*WIDTH   , // pointer at the beggining of n-th row
                            BLOCK_SIZE          , // horizontal length for square
                            WIDTH               , // image width
                            (ir/BLOCK_SIZE) % 2   // offset to create the checker pattern
                            );
    }

    // validation
    printf("\n");
    printf("Validation \n");
    printf("\n");
    for (ir = 0; ir < WIDTH; ir++)
    {
        for ( ic = 0; ic < HEIGHT; ic++)
        {
            printf("%d,", pixels[ir*WIDTH + ic] );
        }
        printf("\n");
    }

    return 0;
}

对我来说似乎很格格不入:http: //ideone.com/gp9so6

于 2013-08-07T13:11:30.460 回答