-2
나는 내 프로젝트에 약간의 어려움이있다. 256x256 bmp 이미지에서 RGB 값을 얻었습니다. 그러나, 나는 그 RGB 값을 압축하는 허프만 코딩을 사용하여 계속하는 방법을 모르겠다. 아무도 도와 줄 수 있습니까? 당신의 도움을 주셔서 감사합니다.허프만 코딩을 사용한 이미지 압축
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*-------PROTOTYPES-------*/
long getImageInfo(FILE*, long, int);
void copyImageInfo(FILE* inputFile, FILE* outputFile);
void copyColorTable(FILE* inputFile, FILE* outputFile, int nColors);
//void bmpsave (FILE*, unsigned char , int , int);
/*------STRUCTURES--------*/
typedef struct {int rows; int cols; unsigned char* data;} sImage;
int main(int argc, char* argv[])
{
FILE *bmpInput, *rasterOutput, *bmpOutput,*RedText,*GreenText,*BlueText,*ErrorRedText,*ErrorBlueText,*ErrorGreenText;
FILE *entroGreen,*entroBlue,*entroRed;
sImage originalImage;
unsigned char someChar;
unsigned char *pChar;
long fileSize;
int vectorSize, nColors;
int totalGCount=0, totalBCount=0,totalRCount=0;
int r, c, i,j,k=0;
int redValue, greenValue, blueValue;
int dummyRed=0 ,dummyGreen=0, dummyBlue=0;
int count[256] = {0},countRed[256]= {0},countBlue[256]= {0},countGreen[256]= {0};
double EntropyGreen, EntropyBlue, EntropyRed;
//int error[414720];
//int Red[400][720];
//int Green[400][720];
//int Blue[400][720];
unsigned int uint1;
short word1;
unsigned char byte1, byte2;
FILE *imdata;
int **errorGreen;
int **errorRed;
int **errorBlue;
int **Red;
int **Blue;
int **Green;
int **b;
b = malloc (256 * sizeof (int));
for (i = 0; i < 256; ++i)
b[i] = malloc (256 * sizeof (int));
errorGreen = malloc (256 * sizeof (int));
for (i = 0; i < 256; ++i)
errorGreen[i] = malloc (256 * sizeof (int));
errorRed = malloc (256 * sizeof (int));
for (i = 0; i < 256; ++i)
errorRed[i] = malloc (256 * sizeof (int));
errorBlue = malloc (256 * sizeof (int));
for (i = 0; i < 256; ++i)
errorBlue[i] = malloc (256 * sizeof (int));
//error = (int *) malloc (414720 * sizeof (int)); //Dynamic Memmory Allocation of 1D Array
Red = malloc (256 * sizeof (int));
for (i = 0; i < 256; ++i)
Red[i] = malloc (256 * sizeof (int));
Green = malloc (256 * sizeof (int));
for (i = 0; i < 256; ++i)
Green[i] = malloc (256 * sizeof (int));
Blue = malloc (256 * sizeof (int));
for (i = 0; i < 256; ++i)
Blue[i] = malloc (256 * sizeof (int));
/*--------INITIALIZE POINTER----------*/
someChar = '0';
pChar = &someChar;
if(argc < 2)
{
printf("Usage: %s bmpInput.bmp\n", argv[0]);
exit(0);
}
printf("Reading file %s\n", "Kirschen_256.bmp");
/*----DECLARE INPUT AND OUTPUT FILES----*/
bmpInput = fopen("Kirschen_256.bmp", "rb");
/*RedText = fopen("Red.txt", "w");
BlueText = fopen("Blue.txt", "w");
GreenText = fopen("Green.txt", "w");*/
entroGreen = fopen("entroGreen.txt", "w");
entroRed = fopen("entroRed.txt", "w");
entroBlue = fopen("entroBlue.txt", "w");
ErrorRedText = fopen("ErrorRed.txt", "w");
ErrorBlueText = fopen("ErrorBlue.txt", "w");
ErrorGreenText = fopen("ErrorGreen.txt", "w");
rasterOutput = fopen("Kirschen_256.txt", "w");
bmpOutput = fopen("Kirschen_256().bmp", "wb");
fseek(bmpInput , 0L , SEEK_END);
//fseek is a C function belonging to the ANSI C standard library,
//and included in the file stdio.h. Its purpose is to change the file position indicator for the specified stream.
/*-----GET BMP DATA-----*/
originalImage.cols = (int)getImageInfo(bmpInput, 18, 4);
originalImage.rows = (int)getImageInfo(bmpInput, 22, 4);
fileSize = getImageInfo(bmpInput, 2, 4);
nColors = getImageInfo(bmpInput, 46, 4);
//vectorSize = fileSize - (14 + 40 + 4*nColors);
/*----PRINT DATA TO SCREEN-----*/
printf("Width: %d\n", originalImage.cols);
printf("Height: %d\n", originalImage.rows);
printf("File size: %ld\n", fileSize);
printf("Bits/pixel: %d\n", getImageInfo(bmpInput, 28, 4));
printf("No. colors: %d\n", nColors);
//printf("Vector size: %d\n", vectorSize);
copyImageInfo(bmpInput, bmpOutput);
//copyColorTable(bmpInput, bmpOutput, nColors);
/*----FOR 24-BIT BMP, THERE IS NO COLOR TABLE-----*/
fseek(bmpInput , 54 , SEEK_SET);
fseek(bmpOutput , 54 , SEEK_SET);
/*-----------READ RASTER DATA-----------*/
for(r=0; r<=originalImage.rows-1; r++)
{
for(c=0; c<=originalImage.cols-1; c++)
{
/*----READ FIRST BYTE TO GET BLUE VALUE-----*/
fread(pChar, sizeof(char), 1, bmpInput);
blueValue = *pChar;
Blue[r][c]=*pChar;
if (r==0||c==0){
errorBlue[r][c]=abs(dummyBlue-blueValue);
countBlue[abs(dummyBlue-blueValue)]++;
count[abs(dummyBlue-blueValue)]++;
totalBCount++;
}
else{
errorBlue[r][c]=abs(((dummyBlue+Blue[r-1][c]+Blue[r-1][c-1])/3)-blueValue);
countBlue[abs(((dummyBlue+Blue[r-1][c]+Blue[r-1][c-1])/3)-blueValue)]++;
count[abs(((dummyBlue+Blue[r-1][c]+Blue[r-1][c-1])/3)-blueValue)]++;
totalBCount++;
}
//error[k]=abs(dummyBlue-blueValue);
//k++;
*pChar=dummyBlue;
fwrite(pChar, sizeof(char), 1, bmpOutput);
dummyBlue=blueValue;
/*-----READ NEXT BYTE TO GET GREEN VALUE-----*/
fread(pChar, sizeof(char), 1, bmpInput);
greenValue = *pChar;
Green[r][c]=*pChar;
if (r==0||c==0){
errorGreen[r][c]=abs(dummyGreen-greenValue);
countGreen[abs(dummyGreen-greenValue)]++;
count[abs(dummyGreen-greenValue)]++;
totalGCount++;
}
else{
errorGreen[r][c]=abs(((dummyGreen+Green[r-1][c]+Green[r-1][c-1])/3)-greenValue);
countGreen[abs(((dummyGreen+Green[r-1][c]+Green[r-1][c-1])/3)-greenValue)]++;
count[abs(((dummyGreen+Green[r-1][c]+Green[r-1][c-1])/3)-greenValue)]++;
totalGCount++;
}
*pChar=dummyGreen;
fwrite(pChar, sizeof(char), 1, bmpOutput);
dummyGreen=greenValue;
/*-----READ NEXT BYTE TO GET RED VALUE-----*/
fread(pChar, sizeof(char), 1, bmpInput);
redValue = *pChar;
Red[r][c]=*pChar;
if (r==0||c==0){
errorRed[r][c]=abs(dummyRed-redValue);
countRed[abs(dummyRed-redValue)]++;
count[abs(dummyRed-redValue)]++;
totalRCount++;
}
else{
errorRed[r][c]=abs(((dummyRed+Red[r-1][c]+Red[r-1][c-1])/3)-redValue);
countRed[abs(((dummyRed+Red[r-1][c]+Red[r-1][c-1])/3)-redValue)]++;
count[abs(((dummyRed+Red[r-1][c]+Red[r-1][c-1])/3)-redValue)]++;
totalRCount++;
}
*pChar=dummyRed;
fwrite(pChar, sizeof(char), 1, bmpOutput);
dummyRed=redValue;
/*---------PRINT TO TEXT FILE---------*/
fprintf(rasterOutput, "(%d %d) = \tRed \t%d", r, c, redValue);
fprintf(rasterOutput, "\tGreen \t%d \tBlue \t%d\n", greenValue, blueValue);
/*-----read data, reflect and write to output file----*/
//fseek(bmpOutput, 54 , SEEK_SET);
//fwrite(pChar, sizeof(char), 1, bmpOutput);
}
}
for (j=0; j<256; j++) {
for (i=255; i>=0; i--) {
if(i>=256-(count[j]/16))
b[i][j] = 0x00;
else
b[i][j] = 0xFF;
}
}
imdata = fopen("Kirschen_256after4", "wb");
/* if (imdata == NULL) {
printf("%s open error.\n", imname); exit(0);
}
*/
byte1 = 'B'; byte2 = 'M';
fwrite(&byte1, 1, 1, imdata); fwrite(&byte2, 1, 1, imdata);
uint1 = 54 + 4*256 + originalImage.cols*originalImage.rows; fwrite(&uint1, 4, 1, imdata);
word1 = 0; fwrite(&word1, 2, 1, imdata); fwrite(&word1, 2, 1, imdata);
uint1 = 54 + 4*256; fwrite(&uint1, 4, 1, imdata);
uint1 = 40; fwrite(&uint1, 4, 1, imdata);
fwrite(&originalImage.cols, 4, 1, imdata); fwrite(&originalImage.rows, 4, 1, imdata);
word1 = 1; fwrite(&word1, 2, 1, imdata);
word1 = 8; fwrite(&word1, 2, 1, imdata);
uint1 = 0; fwrite(&uint1, 4, 1, imdata);
uint1 = originalImage.cols*originalImage.rows; fwrite(&uint1, 4, 1, imdata);
j = 11811; fwrite(&j, 4, 1, imdata); fwrite(&j, 4, 1, imdata);
uint1 = 256; fwrite(&uint1, 4, 1, imdata);
uint1 = 0; fwrite(&uint1, 4, 1, imdata);
for (i=0; i<256; i++) {
byte1 = i;
fwrite(&byte1, 1, 1, imdata); fwrite(&byte1, 1, 1, imdata);
fwrite(&byte1, 1, 1, imdata); fwrite(&byte1, 1, 1, imdata);
}
for (i=originalImage.rows-1; i>=0; i--) {
for (j=0; j<originalImage.cols; j++) {
fwrite(&b[i][j], 1, 1, imdata);
}
}
fclose(imdata);
for (i=0; i<256; i++) {
if (countGreen[i]==0)
EntropyGreen += 0;
else
EntropyGreen += ((double)countGreen[i]/(double)totalGCount) * (log2 ((double)1/((double)countGreen[i]/(double)totalGCount)));
if (countRed[i]==0)
EntropyRed += 0;
else
EntropyRed += ((double)countRed[i]/(double)totalRCount) * (log2 ((double)1/((double)countRed[i]/(double)totalRCount)));
if (countBlue[i]==0)
EntropyBlue +=0;
else
EntropyBlue += ((double)countBlue[i]/(double)totalBCount) * (log2 ((double)1/((double)countBlue[i]/(double)totalBCount)));
}
fprintf(entroGreen, "Entropy= %f", EntropyGreen);
fprintf(entroRed, "Entropy= %f", EntropyRed);
fprintf(entroBlue, "Entropy= %f", EntropyBlue);
for (i = 0; i < 256; i++) {
for (j = 0; j < 256; j++) {
fprintf(ErrorRedText, "[%d][%d] = %2d\n", i, j, errorRed[i][j]);
fprintf(ErrorGreenText, "[%d][%d] = %2d\n", i, j, errorGreen[i][j]);
fprintf(ErrorBlueText, "[%d][%d] = %2d\n", i, j, errorBlue[i][j]);
fprintf (ErrorRedText,"\n");
fprintf (ErrorBlueText,"\n");
fprintf (ErrorGreenText,"\n");
}
}
/*for (i = 0; i < 768; i++) {
for (j = 0; j < 1024; j++) {
fprintf(RedText, "a[%d][%d] = %2d\n", i, j, Red[i][j]);
fprintf(GreenText, "a[%d][%d] = %2d\n", i, j, Green[i][j]);
fprintf(BlueText, "a[%d][%d] = %2d\n", i, j, Blue[i][j]);
}
fprintf (RedText,"\n");
fprintf (BlueText,"\n");
fprintf (GreenText,"\n");
}*/
/*for (i = 0; i < 414720; i++){
fprintf(ErrorText, "error[%d] = %d\n",i,error[i]);
fprintf (ErrorText,"\n");
}*/
// PrintHistogram(freq_array, NUM_RANGE);
fclose(bmpInput);
/*fclose(RedText);
fclose(GreenText);
fclose(BlueText);*/
fclose(ErrorRedText);
fclose(ErrorGreenText);
fclose(ErrorBlueText);
fclose(rasterOutput);
fclose(bmpOutput);
fclose(entroGreen);
fclose(entroRed);
fclose(entroBlue);
return 0;
}
/*----GET IMAGE INFO SUBPROGRAM------*/
long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value=0L;
int i;
unsigned char dummy;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, offset, SEEK_SET);
for(i=1; i<=numberOfChars; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
/* calculate value based on adding bytes */
value = (long)(value + (*ptrC)*(pow(256, (i-1))));
}
return(value);
}
/*-------------COPIES HEADER AND INFO HEADER----------------*/
void copyImageInfo(FILE* inputFile, FILE* outputFile)
{
unsigned char *ptrC;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, 0L, SEEK_SET);
fseek(outputFile, 0L, SEEK_SET);
for(i=0; i<=50; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
fwrite(ptrC, sizeof(char), 1, outputFile);
}
}
/*----------------COPIES COLOR TABLE-----------------------------*/
void copyColorTable(FILE* inputFile, FILE* outputFile, int nColors)
{
unsigned char *ptrC;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, 54L, SEEK_SET);
fseek(outputFile, 54L, SEEK_SET);
for(i=0; i<=(4*nColors); i++) /* there are (4*nColors) bytesin color table */
{
fread(ptrC, sizeof(char), 1, inputFile);
fwrite(ptrC, sizeof(char), 1, outputFile);
}
}
어떤 비트에 붙어 있습니까? 귀하의 코드는 huffman과 관련된 것을 작성하기 시작한 것으로 보이지 않습니다. 개념에 대해 혼란 스러우면 이해하지 못하는 개념에 대해 구체적인 질문을하고 관련성없는 코드를 게시하지 마십시오. huffman이 코드로 작업하는 방법을 혼동하는 경우 문제를 나타내는 최소한의 컴파일 가능한 예제를 게시하십시오. –
이 숙제가 있습니까? 그렇다면 숙제 레이블을 추가하십시오. – bta