728x90
728x90
CNN에서 사용했던 패딩과 똑같은 개념입니다.
2023.12.13 - [인공지능/공부] - CNN - 기본 개념
중앙값으로 필터를 취하는 것이다.
여기선 평균값을 취하는 필터이다.
여기서 한번 진행할 때 마다 원래 행렬 크기가 k*k -> (k-2) * (k-2)가 되므로 padding을 붙여준다.
//padding
int padding = 1;
int pwidth = width + padding * 2;
int pheight = height + padding * 2;
int psize = pwidth * pheight;
double* py;
py = (double*)calloc(pwidth * pheight, sizeof(double));
// 일단 원본 값 집어넣기
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
py[(j + padding) * pwidth + (i + padding)] = y2[j * width + i];
}
}
// 패딩 값 집어넣기
//하
for (int p = 0; p < padding; p++) {
for (int i = 0; i < width; i++) {
py[(p)*pwidth + (i + padding)] = y2[0 * width + i];
}
}
//좌
for (int p = 0; p < padding; p++) {
for (int j = 0; j < height; j++) {
py[(j+padding) * pwidth + p] = y2[j * width];
}
}
//우
for (int p = 0; p < padding; p++) {
for (int j = 0; j < height; j++) {
py[(j + padding) * pwidth + (width + padding)+ p] = y2[(j+1) * width-1];
}
}
//상
for (int p = 0; p < padding; p++) {
for (int i = 0; i < width; i++) {
py[(p+ width + padding)*pwidth + (i + padding)] = y2[(height-1) * width + i];
}
}
// 좌하 ( 0,0) ~ (padding-1,padding-1)
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(j) * pwidth + (i)] = y2[0 * width + 0];
}
}
// 우하 (0,pwidth-1 -padding) ~ (padding-1,pwidth-1)
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(j)*pwidth + (width + padding + i)] = y2[1 * width-1];
}
}
// 좌상
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(height + padding+j)*pwidth + (i)] = y2[(height-1) * width];
}
}
//우상
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(height + padding + j) * pwidth + (width + padding + i)] = y2[(height) * width-1];
}
}
일단은 바로 주변값을 집어 넣는 코드이다.
나중에 평균을 취하든 할 것인데 지금은 이거 짜는데만 수정을 많이해서....
// filter
int fsize = 3;
// mean filter
printf("filter start\n");
double* filter;
filter = (double*)calloc(fsize * fsize, sizeof(double));
for (int i = 0; i < fsize * fsize; i++) {
filter[i] = 1.0 / (fsize * fsize);
}
// 3*3 Gussian Filter
double G3filter[] = {1.0/16,2.0/16,1.0/16,2.0/16,4.0/16,2.0/16,1.0/16,2.0/16,1.0/16};
for (int i = 0; i < 9; i++) printf("%lf ", G3filter[i]);
printf("\n");
double G5filter[] = {1/273.0, 4/ 273.0, 7/ 273.0, 4/ 273.0, 1/ 273.0, 4/ 273.0, 16/ 273.0, 26/ 273.0, 16/ 273.0, 4/ 273.0, 7/ 273.0, 26/ 273.0, 41/ 273.0, 26/ 273.0, 7/ 273.0, 4 / 273.0, 16 / 273.0, 26 / 273.0, 16 / 273.0, 4 / 273.0,1 / 273.0, 4 / 273.0, 7 / 273.0, 4 / 273.0, 1 / 273.0 };
for (int i = 0; i < 25; i++) printf("%lf ", G5filter[i]);
double* y3,sumf;
y3 = (double*)calloc(width * height, sizeof(double));
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
sumf = 0;
for (int k = 0; k < fsize; k++) {
for (int l = 0; l < fsize; l++) {
sumf += G3filter[k * fsize + l] * py[(j+k) * pwidth + (i+l)];
}
}
y3[j * width + i] = sumf;
}
//printf("\n");
}
여기는 필터 관련 코드이다
mean이든 가우시안이든 편한 것으로 사용하면 된다.
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<math.h>
int main() {
BITMAPFILEHEADER bmpFile, bmpFile2;
BITMAPINFOHEADER bmpInfo, bmpInfo2;
FILE* inputFile = NULL, * inputFile2 = NULL;
inputFile = fopen("originalY.bmp", "rb");
inputFile2 = fopen("AICenterY_Noise.bmp", "rb");
//inputFile2 = fopen("AICenterY.bmp", "rb");
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;
int height = bmpInfo.biHeight;
int size = bmpInfo.biSizeImage;
int bitCnt = bmpInfo.biBitCount;
int stride = (((bitCnt / 8) * width) + 3) / 4 * 4,max;
double Y, Cb, Cr,*y,*cb,*cr,*y2,mse=0,psnr=0;
printf("width,height,size,bitCnt,stride\n");
printf("%d %d %d %d %d\n",width,height,size,bitCnt,stride);
int width2 = bmpInfo2.biWidth;
int height2 = bmpInfo2.biHeight;
int size2 = bmpInfo2.biSizeImage;
int bitCnt2 = bmpInfo2.biBitCount;
int stride2 = (((bitCnt2 / 8) * width2) + 3) / 4 * 4;
printf("%d %d %d %d %d\n", width2, height2, size2, bitCnt2, stride2);
unsigned char* inputImg = NULL, * outputImg = NULL,* I, * inputImg2 = NULL;
inputImg = (unsigned char*)calloc(size, sizeof(unsigned char));
inputImg2 = (unsigned char*)calloc(size, sizeof(unsigned char));
outputImg = (unsigned char*)calloc(size, sizeof(unsigned char));
y = (double*)calloc(width* height, sizeof(double));
y2 = (double*)calloc(width * height, sizeof(double));
cb = (double*)calloc(width * height, sizeof(double));
cr = (double*)calloc(width * height, sizeof(double));
I = (unsigned char*)calloc(width * height, sizeof(unsigned char));
fread(inputImg, sizeof(unsigned char), size, inputFile);
fread(inputImg2, sizeof(unsigned char), size, inputFile2);
// input
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
y[j * width + i] = inputImg[j * stride + 3 * i ];
y2[j * width + i] = inputImg2[j * stride + 3 * i ];
}
}
// Algorithm
//padding
int padding = 1;
int pwidth = width + padding * 2;
int pheight = height + padding * 2;
int psize = pwidth * pheight;
double* py;
py = (double*)calloc(pwidth * pheight, sizeof(double));
// 일단 원본 값 집어넣기
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
py[(j + padding) * pwidth + (i + padding)] = y2[j * width + i];
}
}
// 패딩 값 집어넣기
//하
for (int p = 0; p < padding; p++) {
for (int i = 0; i < width; i++) {
py[(p)*pwidth + (i + padding)] = y2[0 * width + i];
}
}
//좌
for (int p = 0; p < padding; p++) {
for (int j = 0; j < height; j++) {
py[(j+padding) * pwidth + p] = y2[j * width];
}
}
//우
for (int p = 0; p < padding; p++) {
for (int j = 0; j < height; j++) {
py[(j + padding) * pwidth + (width + padding)+ p] = y2[(j+1) * width-1];
}
}
//상
for (int p = 0; p < padding; p++) {
for (int i = 0; i < width; i++) {
py[(p+ width + padding)*pwidth + (i + padding)] = y2[(height-1) * width + i];
}
}
// 좌하 ( 0,0) ~ (padding-1,padding-1)
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(j) * pwidth + (i)] = y2[0 * width + 0];
}
}
// 우하 (0,pwidth-1 -padding) ~ (padding-1,pwidth-1)
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(j)*pwidth + (width + padding + i)] = y2[1 * width-1];
}
}
// 좌상
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(height + padding+j)*pwidth + (i)] = y2[(height-1) * width];
}
}
//우상
for (int j = 0; j < padding; j++) {
for (int i = 0; i < padding; i++) {
py[(height + padding + j) * pwidth + (width + padding + i)] = y2[(height) * width-1];
}
}
// filter
int fsize = 3;
// mean filter
printf("filter start\n");
double* filter;
filter = (double*)calloc(fsize * fsize, sizeof(double));
for (int i = 0; i < fsize * fsize; i++) {
filter[i] = 1.0 / (fsize * fsize);
}
// 3*3 Gussian Filter
double G3filter[] = {1.0/16,2.0/16,1.0/16,2.0/16,4.0/16,2.0/16,1.0/16,2.0/16,1.0/16};
for (int i = 0; i < 9; i++) printf("%lf ", G3filter[i]);
printf("\n");
double G5filter[] = {1/273.0, 4/ 273.0, 7/ 273.0, 4/ 273.0, 1/ 273.0, 4/ 273.0, 16/ 273.0, 26/ 273.0, 16/ 273.0, 4/ 273.0, 7/ 273.0, 26/ 273.0, 41/ 273.0, 26/ 273.0, 7/ 273.0, 4 / 273.0, 16 / 273.0, 26 / 273.0, 16 / 273.0, 4 / 273.0,1 / 273.0, 4 / 273.0, 7 / 273.0, 4 / 273.0, 1 / 273.0 };
for (int i = 0; i < 25; i++) printf("%lf ", G5filter[i]);
double* y3,sumf;
y3 = (double*)calloc(width * height, sizeof(double));
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
sumf = 0;
for (int k = 0; k < fsize; k++) {
for (int l = 0; l < fsize; l++) {
sumf += G3filter[k * fsize + l] * py[(j+k) * pwidth + (i+l)];
}
}
y3[j * width + i] = sumf;
}
//printf("\n");
}
//get Quality
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);
// output
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
outputImg[j * stride + 3 * i + 0] = (unsigned char)(y3[j * width + i]>255 ? 255 : (y3[j * width + i]< 0 ? 0 : y3[j * width + i]));
outputImg[j * stride + 3 * i + 1] = (unsigned char)(y3[j * width + i] > 255 ? 255 : (y3[j * width + i] < 0 ? 0 : y3[j * width + i]));
outputImg[j * stride + 3 * i + 2] = (unsigned char)(y3[j * width + i] > 255 ? 255 : (y3[j * width + i] < 0 ? 0 : y3[j * width + i]));
}
}
FILE* outputFile = fopen("Output.bmp", "wb");
fwrite(&bmpFile, sizeof(BITMAPFILEHEADER),1,outputFile);
fwrite(&bmpInfo, sizeof(BITMAPINFOHEADER), 1, outputFile);
fwrite(outputImg, sizeof(unsigned char), size, outputFile);
free(outputImg);
fclose(outputFile);
free(inputImg);
free(inputImg2);
free(y);
free(y2);
free(py);
free(y3);
fclose(inputFile);
return 0;
}
총 코드이다.
728x90
'언어 > C' 카테고리의 다른 글
C언어 영상처리 - Histogram Equalization (0) | 2024.04.04 |
---|---|
C언어 영상처리 - Histogram (0) | 2024.04.02 |
영상처리 과제 2 - PSNR 구하기 (0) | 2024.03.28 |
c언어 복습 - 입력, python도 조금 (0) | 2024.03.22 |
C언어 영상처리 - 과제 1 (0) | 2024.03.20 |