изображение read.bmp с использованием qdbmp - PullRequest
0 голосов
/ 15 мая 2018

Я использую библиотеку qdbmc для чтения серого изображения bmp (lena_gray.bmp)

это ссылка на библиотеку

и это мой код:

int read_image(char *filename)
{
struct _BMP* bmp;
UINT    width, height;
UCHAR red,green,blue;

bmp = BMP_ReadFile(filename);
BMP_CHECK_ERROR( stderr, -1 );

/* Get image's dimensions */
 width = BMP_GetWidth( bmp );
 height = BMP_GetHeight( bmp );
 printf("%lu   %lu \n",width,height);

 /* Iterate through all the image's pixels */
 for (int x = 0 ; x < width ; ++x )
 {
     for (int y = 0 ; y < height ; ++y )
     {
         /* Get pixel's RGB values */
         BMP_GetPixelRGB( bmp, x, y, &red, &green, &blue );
         printf("%d \t %d \t %d \n",red,green,blue);
     }
 }
 return 0;
}

ширина и высота отображаются правильно (512 x 512), но значения пикселей правильные, потому что он показывает все нули.

когда я использовал функцию imread () с python, я получил это:

60 160 160 159 161 156 161 159 162 159 160 158 154 162 158 154 156 155
160 160 153 156 154 156 154 156 154 152 155 153 153 155 153 157 155 158
.....

Может кто-нибудь помочь, пожалуйста?

редактировать

Это ссылка на изображение (выберите Лена, 8 бит серого (512 х 512), BMP ) * * Тысяча двадцать-один

1 Ответ

0 голосов
/ 16 мая 2018

Ни один из выводов не является правильным. Серый цвет в растровом изображении в градациях серого имеет вид: (x, x, x), где красный, синий и зеленый совпадают. Поэтому ноль - это неправильно. И и 60 160 160 159 161 156 ... неверно, потому что нет шаблона повторения.

8-битное растровое изображение использует таблицу. Первые 54 байта являются заголовком файла. Затем есть 256 цветов (каждый длиной 4 байта), а затем ширина * высота байтов, где ширина должна быть дополнена, чтобы размер ширины в байтах был кратен 4.

Пиксели растрового изображения начинаются снизу вверх, сначала нужно прочитать строку (начиная снизу), а затем прочитать каждый столбец. Этот код должен напечатать правильный вывод для первых 5 столбцов в каждой строке:

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

#pragma pack(push, 1)
struct my_BITMAPFILEHEADER {
    short bfType;
    int bfSize;
    short bfReserved1;
    short bfReserved2;
    int bfOffBits;
};

struct my_BITMAPINFOHEADER {
    int biSize;
    int biWidth;
    int biHeight;
    short biPlanes;
    short biBitCount;
    int biCompression;
    int biSizeImage;
    int biXPelsPerMeter;
    int biYPelsPerMeter;
    int biClrUsed;
    int biClrImportant;
};
#pragma pack(pop)

int main(void)
{
    if(sizeof(struct my_BITMAPFILEHEADER) != 14)
    {
        printf("stop!\n");
        return 0;
    }

    FILE *fp = fopen("c:\\test\\barbara_gray.bmp", "rb");

    //Read file header
    struct my_BITMAPFILEHEADER fhdr;
    struct my_BITMAPINFOHEADER ihdr;
    fread(&fhdr, sizeof(fhdr), 1, fp);
    fread(&ihdr, sizeof(ihdr), 1, fp);

    if(fhdr.bfType == 'MB' && ihdr.biBitCount == 8 && ihdr.biPlanes == 1)
    {
        //Read table
        unsigned int table[256] = { 0 };
        fread(table, 4, 256, fp);

        int w = ihdr.biWidth;
        int h = ihdr.biHeight;

        //Find width in bytes. Use a math trick to make sure it's divisble by 4
        int w_in_bytes = ((w * 8 + 31) / 32) * 4;
        int size = w_in_bytes * h;

        //Read pixels
        unsigned char *pixels = malloc(size);
        fread(pixels, 1, size, fp);

        //Read from bottom to top:
        for(int row = h - 1; row >= 0; row--)
        {
            printf("%3d: ", h - 1 - row);
            //Read from left to right:
            for(int col = 0; col < w; col++)
            {
                int pos = row * w_in_bytes + col;
                unsigned char color_index = pixels[pos];
                unsigned int clr = table[color_index];
                printf("%02X%02X%02X ", 
                    clr & 0xFF, (clr >> 8) & 0xFF, (clr >> 16) & 0xFF);
                if(col > 5) break;
            }
            printf("\n");
        }

        free(pixels);
    }

    printf("\n");
    fclose(fp);
    return 0;
}
...