简体   繁体   English

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

[英]I'm reading the RGB values of pixels from a BMP file and not getting the correct values

I followed the code at this link read pixel value in bmp file to be able to read the RGB values of pixels and when I have the entire image as one color and read a random pixel's values they are correct. 我按照此链接上的代码读取bmp文件中的像素值,从而能够读取像素的RGB值,当我将整个图像作为一种颜色并读取随机像素的值时,它们是正确的。 After this I tried to make it so the function would also try and find how many unique colors there were so I added a box with a different color to the image but the function still only finds one color. 在此之后,我尝试制作该函数,以便该函数还将尝试查找有多少种独特的颜色,因此我在图像中添加了一个具有不同颜色的框,但该函数仍然只能找到一种颜色。 I'm wondering if maybe I'm somehow not looking at all the bytes contained in the BMP but I'm not sure how that would be as I'm new to trying this stuff. 我想知道是否也许我不以某种方式查看BMP中包含的所有字节,但是我不确定如何尝试,因为我是新手。

To make sure the code wasn't finding different colored pixels but failing to add them to the list of unique pixels I tried printing output when a color is found that is different from the one that is always found but no output ever came from it. 为了确保代码没有找到不同的彩色像素,但是没有将它们添加到唯一像素列表中,我尝试在发现一种不同于始终找到的颜色但没有任何输出的颜色时打印输出。

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 This is the picture I'm using so there should be two colors found but the code only finds red pixels. https://imgur.com/a/dXllIWL这是我正在使用的图片,因此应该找到两种颜色,但是代码只能找到红色像素。

Your problem is that you are always checking the RGB values at (0,0) 您的问题是您始终检查(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];

i and j defines the X and Y position of the pixel you are checking, but notice that you never change those in the loop. ij定义了要检查的像素的X和Y位置,但请注意,您永远不要在循环中更改像素位置。 Your loop will keep doing the same thing over and over again. 您的循环将一遍又一遍地执行相同的操作。 What you probably want is a double loop, going through all coordinates in your image: 您可能想要的是一个双循环,遍历图像中的所有坐标:

   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];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM