언어/C

C언어 영상처리 - data 파일에 넣은 사진 psnr 자동 계산하기

이게될까 2024. 5. 16. 15:46
728x90
728x90
#define _CRT_SECURE_NO_WARNINGS
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <windows.h>

double threshold = 0;

void CumulativeHisto(int height, int width, double* y, int size, int stride, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo);
void applyPaddingWithAverage(double* paddedImg, int height, int width, int padding, double* origImg);
void calFilter(double* y3, double* py, int fsize, double* filter, int height, int width, int pwidth);
double median(double* arr, int size);
void calMedianFilter(double* y3, double* py, int fsize, int height, int width, int pwidth);
void bilateralFilter(double* paddedImg, double* outputImg, int width, int height, int pwidth, int pheight, int d, double sigmaColor, double sigmaSpace);
void getQulity(double* y, double* y3, int width, int height, int bitCnt, double* psnr);
void upSp(int ratio, double* org, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, double* upy);
void bilinearUpsampling(int ratio, double* org, double* ups, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, double* upy);
void bilinearUpsample(int ratio, double* org, double* ups, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, double* upy);
void nTapInterpolation(int ratio, double* org, double* ups, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, int n, double* upy);
void makeOutFile(BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, char* fileName, double* y);
void sobelEdgeMap(double* y, int width, int height, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, double* edgey);
void hybridFilter(double* y3, double* py, double* edgey, int fsize, int height, int width, int pwidth, double* gFilter);
double cubicInterpolate(double p0, double p1, double p2, double p3, double x);
double bicubicInterpolate(double p[4][4], double x, double y);
void bicubicUpsample(int ratio, double* org, double* ups, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, double* upy);

void processImagePairs(const char* dirPath) {
    DIR* dir;
    struct dirent* ent;
    FILE* inputFile = NULL, * inputFile2 = NULL;
    BITMAPFILEHEADER bmpFile, bmpFile2;
    BITMAPINFOHEADER bmpInfo, bmpInfo2;

    double totalPsnr = 0;
    int count = 0;

    if ((dir = opendir(dirPath)) != NULL) {
        while ((ent = readdir(dir)) != NULL) {
            if (strstr(ent->d_name, "y.bmp") != NULL && !strstr(ent->d_name, "yy.bmp")) {
                // Construct the corresponding "yy" file name
                char filePath1[256], filePath2[256];
                snprintf(filePath1, sizeof(filePath1), "%s/%s", dirPath, ent->d_name);
                // Replace "y.bmp" with "yy.bmp"
                strcpy(filePath2, filePath1);
                strcpy(filePath2 + strlen(filePath2) - 5, "yy.bmp");

                inputFile = fopen(filePath1, "rb");
                inputFile2 = fopen(filePath2, "rb");

                if (inputFile == NULL || inputFile2 == NULL) {
                    printf("Unable to open file %s or %s\n", filePath1, filePath2);
                    if (inputFile) fclose(inputFile);
                    if (inputFile2) fclose(inputFile2);
                    continue;
                }

                fread(&bmpFile, sizeof(BITMAPFILEHEADER), 1, inputFile);
                fread(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, inputFile);    
                fread(&bmpFile2, sizeof(BITMAPFILEHEADER), 1, inputFile2);
                fread(&bmpInfo2, sizeof(BITMAPINFOHEADER), 1, inputFile2);

                int width = bmpInfo.biWidth, height = bmpInfo.biHeight, size = bmpInfo.biSizeImage, bitCnt = bmpInfo.biBitCount, stride = (((bitCnt / 8) * width) + 3) / 4 * 4;
                int width2 = bmpInfo2.biWidth, height2 = bmpInfo2.biHeight, size2 = bmpInfo2.biSizeImage, bitCnt2 = bmpInfo2.biBitCount, stride2 = (((bitCnt2 / 8) * width2) + 3) / 4 * 4;

                double* y = (double*)calloc(width * height, sizeof(double));
                double* y2 = (double*)calloc(width * height, sizeof(double));
                double mse = 0, psnr = 0, * edgey;
                edgey = (double*)calloc(width2 * height2, sizeof(double));

                unsigned char* inputImg = (unsigned char*)calloc(size, sizeof(unsigned char));
                unsigned char* inputImg2 = (unsigned char*)calloc(size, sizeof(unsigned char));

                fread(inputImg, sizeof(unsigned char), size, inputFile);
                fread(inputImg2, sizeof(unsigned char), size, inputFile2);

                for (int j = 0; j < height; j++) {
                    for (int i = 0; i < width; i++) {
                        y[j * width + i] = inputImg[j * stride + 3 * i];
                    }
                }
                for (int j = 0; j < height2; j++) {
                    for (int i = 0; i < width2; i++) {
                        y2[j * width2 + i] = inputImg2[j * stride2 + 3 * i];
                    }
                }

                // Process and calculate PSNR
    
                // Print file names before calculating PSNR
                printf("Processing files: %s and %s\n", filePath1, filePath2);
                getQulity(y, upy, width, height, bitCnt, &psnr);
                totalPsnr += psnr;
                count++;

                free(inputImg);
                free(inputImg2);
                free(y);
                free(y2);
                free(py);
                free(y3);
                free(edgey);
                free(upy);
                free(edgey2);
                free(py2);

                fclose(inputFile);
                fclose(inputFile2);
            }
        }
        closedir(dir);
    } else {
        perror("Could not open directory");
    }

    if (count > 0) {
        printf("Average PSNR: %.2lf\n", totalPsnr / count);
    } else {
        printf("No valid image pairs found.\n");
    }
}

int main() {
    processImagePairs("C:\\data");
    return 0;
}

void getQulity(double* y, double* y3, int width, int height, int bitCnt, double* psnr) {
    double mse = 0, max;
    unsigned char org, out;
    for (int j = 0; j < height; j++) {
        for (int i = 0; i < width; i++) {
            org = (unsigned char)(y[j * width + i] > 255 ? 255 : (y[j * width + i] < 0 ? 0 : y[j * width + i]));
            out = (unsigned char)(y3[j * width + i] > 255 ? 255 : (y3[j * width + i] < 0 ? 0 : y3[j * width + i]));
            mse += (double)((org - out) * (org - out));
        }
    }
    mse /= (height * width);
    max = pow(2, bitCnt / 3) - 1;
    *psnr = mse != 0.0 ? 10.0 * log10(max * max / mse) : 99.99;
    printf("mse = %.2lf\npsnr = %.2lf\n", mse, *psnr);
}

// 나머지 함수는 그대로 유지됩니다.

요즘 GPT 똑똑 하네요...

psnr은 올려야 할거 같은데.... 일단은.... 이제 사진 많이 많이 찍어야 겠네요

 

728x90