当前位置: 首页 > 知识库问答 >
问题:

我正在从 BMP 文件中读取像素的 RGB 值,但未获得正确的值

蒋波光
2023-03-14

我按照此链接处的代码读取bmp文件中的像素值,以便能够读取像素的RGB值,当我将整个图像作为一种颜色并读取随机像素值时,它们是正确的。在此之后,我尝试制作它,以便函数也会尝试查找有多少独特的颜色,所以我添加了一个不同颜色的框到图像中,但函数仍然只能找到一种颜色。我想知道我是否不知何故没有查看BMP中包含的所有字节,但我不确定这会是怎样的,因为我是新尝试这种东西的。

为了确保代码没有找到不同颜色的像素,但未能将它们添加到唯一像素列表中,当发现颜色与始终找到的颜色不同但从未输出时,我尝试打印输出。

struct Color {
int R = -1;
int G = -1;
int B = -1;
};

unsigned char* readBMP(char* filename) {
int i;
FILE* f = fopen(filename, "rb");
unsigned char info[54];
fread(info, sizeof(unsigned char), 54, f);

int width = *(int*)&info[18]; //the reason *(int*) is used here because there's an integer stored at 18 in the array that indicates how wide the BMP is
int height = *(int*)&info[22]; // same reasoning for *(int*)

int size = 3 * width * height;
unsigned char* data = new unsigned char[size];
fread(data, sizeof(unsigned char), size, f);
fclose(f);

// windows has BMP saved as BGR tuples and this switches it to RGB
for(i = 0; i < size; i += 3){
    unsigned char tmp = data[i];
    data[i] = data[i+2];
    data[i+2] = tmp;
}

i = 0; // i is the x value of the pixel that is having its RGB values checked
int j = 0; // j is the y value of the pixel that is having its RGB values checked
unsigned char R = data[3 * (i * width + j)]; // value of R of the pixel at (i,j)
unsigned char G = data[3 * (i * width + j) + 1]; // value of G of the pixel at (i,j)
unsigned char B = data[3 * (i * width + j) + 2]; // value of B of the pixel at (i,j)

std::cout << "value of R is " << int(R);
std::cout << " value of G is " << int(G);
std::cout << " value of B is " << int(B);

Color num_colors[5];
int count;
int z;
int flag;
int iterator;
int sum;
for(count = 0; count < size; count += 1){
    unsigned char R = data[3 * (i * width + j)];
    unsigned char G = data[3 * (i * width + j) + 1];
    unsigned char B = data[3 * (i * width + j) + 2];
    sum = int(R) + int(G) + int(B);
    if(sum != 301) {// 301 is the sum of the RGB values of the color that the program does manage to find
        std::cout << sum;
    }
    flag = 0;
    for(z = 0; z < 5; z += 1){
        if(num_colors[z].R == R && num_colors[z].G == G && num_colors[z].B == B){
            flag = 1;
        }
    }
    if(flag == 1){
        continue;
    }
    iterator = 0;
    while(num_colors[iterator].R != -1){
        iterator += 1;
    }
    num_colors[iterator].R = R;
    num_colors[iterator].G = G;
    num_colors[iterator].B = B;
}

int number = 0;
for(int r = 0; r < 5; r += 1){
    std::cout << "\nValue of R here: " << num_colors[r].R;
    if(num_colors[r].R != -1){
        number += 1;
    }
}
std::cout << "\nNumber of colors in image: " << number;
return data;
}

https://imgur.com/a/dXllIWL这是我正在使用的图片,所以应该找到两种颜色,但代码只找到红色像素。

共有1个答案

曹焱
2023-03-14

您的问题是,总是在(0,0)处检查RGB值

i = 0; // i is the x value of the pixel that is having its RGB values checked
int j = 0; // j is the y value of the pixel that is having its RGB values checked
...
for(count = 0; count < size; count += 1){
    unsigned char R = data[3 * (i * width + j)];
    unsigned char G = data[3 * (i * width + j) + 1];
    unsigned char B = data[3 * (i * width + j) + 2];

ij 定义了您正在检查的像素的 X 和 Y 位置,但请注意,您永远不会在循环中更改它们。你的循环会一遍又一遍地做同样的事情。您可能想要的是一个双循环,遍历图像中的所有坐标:

   for(int y=0; y<height; y++)
       for(int x=0; x<width; x++){
          unsigned char R = data[3 * (y * width + x) + 0];
          unsigned char G = data[3 * (y * width + x) + 1];
          unsigned char B = data[3 * (y * width + x) + 2];
 类似资料:
  • 我正在尝试单元测试我的类,它看起来像:- 我想在类B中模拟“method2()”。我知道我们需要有一个B()的mock对象,这样每当我们调用它的方法时,就会发生模拟。这是我试过的 并使用调用它,现在的主要问题是method2被嘲弄了(即method2()的主体没有被执行),但我无法接收C的对象作为响应。 我的测试场景是:- 我想测试类A的method1(),它反过来调用类B的method2(),但

  • 问题内容: 如果使用打开图像,假设我具有像素的坐标,如何获得像素的RGB值? 那么,我该怎么做呢?从空白图形开始,“写入”具有一定RGB值的像素? 如果我不必下载任何其他库,我会希望。 问题答案: 最好使用Python图像库来执行此操作,恐怕这是单独下载的。 执行所需操作的最简单方法是通过Image对象上的load()方法,该方法返回一个像素访问对象,您可以像数组一样对其进行操作: 或者,查看Im

  • 我试图设置cookie来定义用户首选的语言。我通过一个指向助手控制器的链接做到了这一点: /设置区域设置/{locale} 我知道这是正确的,因为如果我这样做: 它显示所选择的正确区域设置。所以下一步是使用中间件实际应用这个选择的语言环境,我把它命名为“设置语言环境”: 但如果我执行 在中间件中,它读取所有加扰的cookie。所以我的问题是为什么它会这样做,我如何从这里正确地读取cookie?

  • 问题内容: 使用GoogleAppEngine(Go)读取文件的正确方法是什么? 在Java中,我读到了,是否有等效的功能? 问题答案: 您可以从App Engine上的文件中读取文件,也可以从计算机上运行的Go应用程序中的文件中读取文件。 注意事项: 您应该使用 相对 文件路径,而不是绝对路径。工作目录是应用程序的根文件夹(文件所在的位置)。 Go代码只能读取属于 应用程序 文件的文件,因此,如

  • 我理解下面的代码可以正常工作。在阅读Python中的while循环文档时,他们说while表达式应该是True或False,这很有意义。 现在,函数返回字符串。那么这个while循环是如何工作的呢?

  • 好的,正如标题所示,我的问题是正确地从python中的windows-1252编码文件中读取输入,并将所述输入插入SQLAlchemy MySql表。 当前系统设置: Windows 7虚拟机,带“罗杰访问控制系统”,输出文件 Ubuntu12.04 LTS虚拟机,带有Windows系统的共享文件夹,因此我可以使用“Python 2.7.3”访问该文件。 现在来看实际问题,对于输入文件,我有一个“