从reg-green-blue img到c中的灰度img

时间:2016-01-08 14:10:25

标签: c image runtime rgb grayscale

我正在编写一个代码来转换RGB格式的图像

RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB

尝试转换为灰度img,但它不起作用。我得到的图片没有着色,但没有预期的那样。更像是黑白而不是灰色。

struct Img {
    unsigned long sizeX;
    unsigned long sizeY;
    char *data;
};

void convernt(Img *image)
{ 
int x,y,i, iRow;
    char* p = image->data;
    int width=image->sizeX;
    int height=image->sizeY;                         
    int rowSize = width*3;                // number of bytes in one row
    int iPix;
    for ( y = 0; y < height; ++y)
    {
        iRow = y*rowSize ;                 // index of first pixel in row y
        for (  x = 0; x < rowSize; x+=3)
        {
            iPix = iRow + x*3;               // index of pixel 
double con=0.2989*p[iPix]+ 0.5870*p[iPix+1]+0.1140*p[iPix+2];
                p[iPix] = con;
                p[iPix+1] = con;
                p[iPix+2] = con;

        }
    }
}

我希望代码与此代码相同,但要更短 应该完全一样 我想我错过了什么

#define NUM_OF_COLORS   256

// perform histogram equalization algorithm on an image
void convert(Img *image)
{ 

    int i,j;

    double* orgHist = (double*)malloc(NUM_OF_COLORS*sizeof(double));
    unsigned char* conversionVector = (unsigned char*)malloc(NUM_OF_COLORS);

    //clear the vector
    for (i=0; i<NUM_OF_COLORS; i++) {
        orgHist[i] = 0;
    }

    //get the histogram of the image
    for (j=0; j<image->sizeY; j++) {
            for (i=0; i<image->sizeX; i++) {
            orgHist[(unsigned char)image->data[3*i + 3*j*image->sizeX + 1]]++;
        }
    }

    //calculate the accumulated histogram of the image
        for (i=1; i<NUM_OF_COLORS; i++) {
            orgHist[i] = orgHist[i] + orgHist[i-1];
    }

    //normalize the histogram
        for (i=0; i<NUM_OF_COLORS; i++) {
            orgHist[i] = orgHist[i]/(image->sizeX*image->sizeY);
        conversionVector[i] = 0;
    }


    // preform the histogram equalization algorithm
    i = 0;
        j = 0;
    while (i<NUM_OF_COLORS) {

        if ((((double)j+1)/256) < orgHist[i]) {
            j++;
        } else {
            conversionVector[i] = j;
            i++;
        }
    }

    // apply the conversion vector on the image
        for (i=0; i<image->sizeX; i++) {
        for (j=0; j<image->sizeY; j++) {
            image->data[3*i + 3*j*image->sizeX + 1] = 
                conversionVector[(unsigned char)image->data[3*i + 3*j*image->sizeX + 1]];
        }
    }

    // copy G values to R&B 
    for (i = 0; i < image->sizeX*image->sizeY; i++) {
        image->data[3*i] = image->data[3*i+1];
        image->data[3*i+2]= image->data[3*i+1];
    }

    free(orgHist);
    free(conversionVector);
}

1 个答案:

答案 0 :(得分:3)

您可以在x循环中将3增加for,或者将x*3添加到索引中。但不要两者。:

for (  x = 0; x < rowSize; x+=3)
                         // ^^^  either x++ ...
{
   iPix = iRow + x*3;               // index of pixel
               // ^^ ... or iRow + x;  
   ...
}

因为rowSize是字节数而不是像素数,所以请调整您的代码:

for (  x = 0; x < rowSize; x+=3 )
{
    iPix = iRow + x; // index of pixel 
    double con = 0.2989*p[iPix] + 0.5870*p[iPix+1] + 0.1140*p[iPix+2];
    p[iPix]   = (char)con;
    p[iPix+1] = (char)con;
    p[iPix+2] = (char)con;
}

这是大图像的解决方案:

#define NUM_OF_COLORS   256

unsigned char rTable[NUM_OF_COLORS];
unsigned char gTable[NUM_OF_COLORS];
unsigned char bTable[NUM_OF_COLORS];

void initTables()
{
    for ( int c = 0; c < NUM_OF_COLORS; c ++ )
    {
        rTable[c] = (unsigned char)(0.2989*c);
        gTable[c] = (unsigned char)(0.5870*c);
        bTable[c] = (unsigned char)(0.1140*c);
    }
}

void convernt(struct Img *image)
{ 
    unsigned char* p = (unsigned char*)image->data;
    int width=image->sizeX;
    int height=image->sizeY;                         
    int rowSize = width*3;                // number of bytes in one row
    for ( int y = 0; y < height; ++y)
    {
        int iRow = y*rowSize ;                 // index of first pixel in row y
        for ( int x = 0; x < rowSize; x+=3 )
        {
            int iPix = iRow + x; // index of pixel
            unsigned char col = rTable[p[iPix]] + gTable[p[iPix+1]] + bTable[p[iPix+2]]; 
            p[iPix]   = col;
            p[iPix+1] = col;
            p[iPix+2] = col;
        }
    }
}