所以我想要一个用棋盘图案覆盖的图像。 这是我到目前为止所提出的:
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
是为图像中的每个像素而不是多个像素调用的。
为什么这段代码不会产生chckerboard模式?你会如何改进它?
答案 0 :(得分: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.data
的类型;我怀疑它是unsigned char*
。)
这对CPU缓存预取非常友好。它对编译器也很友好,它可以进行矢量化和/或执行循环展开。
答案 1 :(得分: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