티스토리 뷰
안녕하세요!
오늘은 원본 raw파일에 대해 새로운 raw파일을 만들어 이미지를 복사하는 방법에 대해서 알아보겠습니다.

일단 raw파일이 무엇인지부터 알아야겠죠.
●raw파일이란?
RAW 파일은 압축 및 가공이 되지 않은 이미지 데이터를 포함하고 있는 파일입니다.
RAW 파일을 사용하면 화이트 밸런스, 노출, 색상 보정 등을 후처리에서 더 유연하게 조정할 수 있어서 사진이나 영상 편집에 유용합니다.
raw파일의 크기로써 512x512 가 많이 사용되는데,
이는 raw파일의 표준해상도이고 메모리 용량도 적합하고
고해상도를 잘 표현할수 있는 256KB의 좋은 크기를 가지고 있기 때문입니다.
● raw파일 복사하는 코드
저희는 다음과 같은 순서로 raw파일을 복사할겁니다.
1) 원본 raw파일을 저장할 메모리를 할당( 이 메모리의 주소를 *ori_pic 이라 하겠습니다. )
2) 복사본 raw파일을 저장할 메모리를 할당( 이 메모리의 주소를 *modi_pic 이라 하겠습니다. )
3) 원본 raw파일의 데이터를 *ori_pic 에 저장한다.
4) *ori_pic 에 있는 데이터를 그대로 *modi_pic 에 복사한다.
5) *modi_pic 에 있는 데이터를 복사본 raw파일에 쓴다.
흥미로운 점은 메모리 할당이 한 가지 방법이 아니라 여러가지 방법이 있는데요.
그 중 1차원 배열과 2차원 배열을 활용한 메모리 할당을 통해 raw파일을 복사 해보도록 하겠습니다.
아래의 코드는 1차월 배열을 이용한 raw파일 복사 코드 입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define VER 512 // FILE의 수직방향 크기
#define HOR 512 // FILE의 수평방향 크기
#define F_SIZE (VER*HOR) // FILE의 크기
unsigned char * alloc_pic (int SIZE);
int main()
{
unsigned char *ori_pic = alloc_pic(F_SIZE); // 원본 raw 데이터를 담을 메모리를 할당.
unsigned char *modi_pic = alloc_pic(F_SIZE); // 복사본 raw 데이터를 담을 메모리를 할당.
FILE *fin1, *fout1;
fin1 = fopen("Lena_512.raw", "rb"); // 읽기모드 스트림 생성
fout1 = fopen("Copy_Lena_512.raw","wb"); // 쓰기모드 스트림 생성
if(!fin1) {printf("ERROR :: File Can't Read\n"); exit(1);} // 파일을 읽는데 문제가 있습니다.
if(!fout1) {printf("ERROR :: File Can't Save\n"); exit(1);} // 파일을 저장하는데 문제가 있습니다.
/*** 데이터 복사 과정 ***/
fread(ori_pic,sizeof(unsigned char),F_SIZE,fin1); // *ori_pic에 원본 raw데이터를 저장.
memcpy(modi_pic,ori_pic,F_SIZE*sizeof(unsigned char)); // *ori_pic에 있는 데이터를 그대로 *modi_pic에 저장.
fwrite(modi_pic,sizeof(unsigned char),F_SIZE,fout1); // *modi_pic에 있는 데이터를 복사본 raw파일에 쓰기.
/*** 파일 닫고 메모리 해제 ***/
fclose(fin1);
fclose(fout1);
free(ori_pic);
free(modi_pic);
printf("success"); // 프로그램이 잘 작동 되는지 확인하는 출력문
return 0;
}
/*** 1차원 배열 메모리 할당 function ***/
unsigned char * alloc_pic (int SIZE)
{
unsigned char * pic;
if((pic=(unsigned char*)calloc(SIZE,sizeof(unsigned char))) == NULL) {
printf("\n malloc_picture : Picture structure \n");
exit(1);
}
return pic;
}
다음은 2차원 배열을 이용한 raw파일 복사 코드입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define VER 512 // FILE의 수직방향 크기
#define HOR 512 // FILE의 수평방향 크기
#define F_SIZE (VER*HOR) // FILE의 크기
unsigned char ** alloc_pic_2d (int width, int height);
int main()
{
int i, j;
unsigned char **ori_pic_2d = alloc_pic_2d(HOR,VER); // 원본 raw 데이터를 담을 메모리를 할당.
unsigned char **modi_pic_2d = alloc_pic_2d(HOR,VER); // 복사본 raw 데이터를 담을 메모리를 할당.
FILE *fin1, *fout1;
fin1 = fopen("Lena_512.raw","rb"); // 읽기모드 스트림 생성
fout1 = fopen("Copy_Lena_512_2d.raw","wb"); // 쓰기모드 스트림 생성
if(!fin1) {printf("ERROR :: File Can't Read\n"); exit(1);} // 파일을 읽는데 문제가 있습니다.
if(!fout1) {printf("ERROR :: File Can't Save\n"); exit(1);} // 파일을 저장하는데 문제가 있습니다.
/*** 데이터 복사 과정 ***/
for( i = 0; i < VER; i++) fread(ori_pic_2d[i],sizeof(unsigned char),VER,fin1);
for( j = 0; j < VER; j++)
{
for( i = 0; i < HOR; i++) modi_pic_2d[j][i] = ori_pic_2d[j][i];
}
for( i = 0; i < VER; i++) fwrite(modi_pic_2d[i],sizeof(unsigned char),HOR,fout1);
/*** 스트림 종료, 메모리 해제 ***/
fclose(fin1);
fclose(fout1);
for ( i = 0; i < VER; i++)
{
free(ori_pic_2d[i]);
free(modi_pic_2d[i]);
}
free(ori_pic_2d);
free(modi_pic_2d);
printf("success"); // 프로그램이 잘 작동 되는지 확인하는 출력문
return 0;
}
/*** 2차원 배열 메모리 할당 function ***/
unsigned char ** alloc_pic_2d(int width, int height)
{
unsigned char **pic;
int i;
if((pic=(unsigned char **)calloc(height,sizeof(unsigned char*)))==NULL){
printf("\n malloc_picture : Picture structure \n");
exit(1);
}
for(i=0;i<height;i++)
{
if((pic[i]=(unsigned char*)calloc(width,sizeof(unsigned char)))==NULL){
printf("\n malloc_picture : Picture structure \n");
exit(1);
}
}
return pic;
}
1차원 배열과 2차원 배열을 활용한 메모리 생성에 대해 자세하게 알아보겠습니다.
1. 1차원 배열을 이용한 메모리 생성
unsigned char * alloc_pic (int SIZE)
{
unsigned char * pic;
if((pic=(unsigned char*)calloc(SIZE,sizeof(unsigned char))) == NULL) {
printf("\n malloc_picture : Picture structure \n");
exit(1);
}
return pic;
}
이 함수는 SIZE 만큼 1차원 으로 픽셀의 값을 저장할 수 있는 메모리를 할당해주는 함수입니다.
if문 안에서 메모리를 할당해주고,
할당되지 않았다면( ==NULL) 오류 메시지를 출력한 후에 즉시 프로그램을 종료 시킵니다.
제대로 할당이 됐으면 할당된 제일 앞 주소를 반환!
아래의 그림과 같이 *pic에 SIZE 만큼 메모리가 할당됩니다!

raw파일의 경우 SIZE == F_SIZE 이므로 512*512의 크기를 가진 1차원 배열이 생성되는 겁니다!
2. 2차원 배열을 이용한 메모리 생성
unsigned char ** alloc_pic_2d(int width, int height)
{
unsigned char **pic;
int i;
if((pic=(unsigned char **)calloc(height,sizeof(unsigned char*)))==NULL){
printf("\n malloc_picture : Picture structure \n");
exit(1);
}
for(i=0;i<height;i++)
{
if((pic[i]=(unsigned char*)calloc(width,sizeof(unsigned char)))==NULL){
printf("\n malloc_picture : Picture structure \n");
exit(1);
}
}
return pic;
이 함수는 width * height 만큼 2차원으로 픽셀의 값을 저장할 수 있는 메모리를 할당해주는 함수입니다.
설명에 앞서 그림으로 먼저 이해하도록 해봅시다.

먼저 첫번째 if문에서는 pic( 파란 부분) 메모리를 생성하는 부분입니다.
마찬가지로, 메모리 생성에 실패했다면 오류메세지를 출력하고 프로그램을 즉시 종료 시킵니다.
두 번째 if문에서는 pic[i] (초록 부분 ) 메모리를 생성합니다.
여기서 주의깊게 보셔야 하는 것은
pic[i] 는 각각 unsigned char의 값(0~255)들로 이루어져 있는 배열의 주소인 것.
pic 은 각각 unsigned char * 의 값( pic[0] ~ pic[Height-1] )들로 이루어져 있는 배열의 주소인 것 입니다.
그렇다면 raw파일의 실질 데이터 ( pixel값 )은 그림의 초록부분 메모리에 위치하게됩니다.
또한, 이 과정을 통해 생성되는 메모리의 크기는
sizeof(unsigned char) * Width * Height + sizeof(unsigned char *) * Height 가 됩니다.
( sizeof(unsgined char*)의 값은 윈도우 운영체제 32비트기준 -> 4, 64비트 기준 -> 8 입니다.)
이 개념을 가지고 코드부분으로 돌아가 이해하도록 합시다.
● 결과
잘 알려진 Lena.raw파일 (흑백)을 이용해 복사 하도록 하겠습니다.
1차원 배열 복사코드 실행 결과



2차원 배열 복사코드 실행 결과



원본 raw파일을 새로운 raw파일에 복사 완료 했습니다!
'C언어' 카테고리의 다른 글
[C언어] 3-2. raw파일을 bmp파일로 변환하기 (0) | 2024.11.11 |
---|---|
[C언어] 3-1. bmp파일을 raw파일로 변환하기 (4) | 2024.11.10 |
+BMP파일 뜯어보기 (1) | 2024.11.09 |
[C언어] 2.기본적인 영상처리(2) (3) | 2024.11.08 |
[C언어] 2.기본적인 영상처리(1) (0) | 2024.11.07 |
- Total
- Today
- Yesterday
- sungroup
- bias
- DEEPLEARNING
- 티스토리챌린지
- 의류분류
- perceptron
- 다층퍼셉트론
- rawtobmp
- bmptoraw
- raw회전이동
- 편향
- RAW
- activationfunction
- 퍼셉트론
- 정보전송
- 오블완
- 현대대수학
- 영상처리 #기초
- 회전이동
- bmp헤더
- BMP
- 활성화함수
- cyclicgroup
- 신경망딥러닝
- fashionMNIST
- errorcorrecting
- MLP
- klein4group
- errordetecting
- generator
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |