Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Gain
- 저조도
- 프로그래머스 lv2
- image sensor
- 아이리스
- 저장소와 동적메모리
- 심도
- camera
- ASCCII
- 실생활알고리즘
- 조건 제어문
- 간단한 앱만들어보기
- Pixel Bit Format
- 변수
- Patch Cleaner
- 변수의 초기화와 대입
- 고정비트레이트
- 렌즈
- Zoom Lense
- AppInventer
- Digital Slow Shutter
- 이미지센서
- 과초점거리
- Depth of Fileld
- c언어
- 카메라
- 무게선별자동화
- main 함수 인자 전달
- CS Mount
- C Mount
Archives
- Today
- Total
카메라 개발자 공부방(SW)
DFT(Discrete Fourier Transform) 본문
반응형
영상 신호를 주파수 영역으로 변환시키는 DFT 코드 입니다. 입력은 pSrc이고 출력은 pReal, pImaginary입니다.
void FourierTransform::DFT(Mat* pSrc, Mat* pReal, Mat* pImaginary)
{
*pReal = Scalar(0);
*pImaginary = Scalar(0);
float* src = pSrc->ptr<float>(0);
float* real = pReal->ptr<float>(0);
float* imaginary = pImaginary->ptr<float>(0);
float N = (float)pSrc->rows;
float M = (float)pSrc->cols;
float NM = N * M;
/* If you want to visualize this frequency domain, you should adjust coefficient scale */
// NM = sqrtf(NM);
uint channel = pSrc->channels();
float pixel = 0;
float term = 0;
for (float u = 0; u < N; u++)
{
for (float v = 0; v < M; v++)
{
src = pSrc->ptr<float>(0);
for (float x = 0; x < N; x++)
{
for (float y = 0; y < M; y++)
{
pixel = (*src);
term = 2 * PI * ((u * x / N) + (v * y / M));
*real += (pixel * cosf(term));
*imaginary -= (pixel * sinf(term));
src += channel;
}
}
*(real) /= NM;
*(imaginary) /= NM;
real += channel;
imaginary += channel;
}
}
}
DFT 결과가 이미지 중앙에 오게끔 좌우 대칭하는 코드입니다.
void FourierTransform::shiftImage(Mat* pSrcReal, Mat* pDstReal)
{
float* srcReal = pSrcReal->ptr<float>(0);
float* dstReal = pDstReal->ptr<float>(0);
int row = pSrcReal->rows / 2;
int col = pSrcReal->cols / 2;
int srcRowVariance[4] = { 0, 0, row, row };
int srcColVariance[4] = { 0, col, 0, col };
int dstRowVariance[4] = { row, row, 0, 0 };
int dstColVariance[4] = { col, 0, col, 0 };
for (int k = 0; k < 4; k++)
{
for (int u = 0; u < row; u++)
{
for (int v = 0; v < col; v++)
{
srcReal = pSrcReal->ptr<float>(u + srcRowVariance[k]) + v + srcColVariance[k];
dstReal = pDstReal->ptr<float>(u + dstRowVariance[k]) + v + dstColVariance[k];
*dstReal = *srcReal;
}
}
}
}
실수부와 허수부를 가시화 하기 위한 코드입니다.
void FourierTransform::Spectrum(Mat* pReal, Mat* pImaginary, Mat* pDst, float scale)
{
float* real = pReal->ptr<float>(0);
float* imaginary = pImaginary->ptr<float>(0);
float* dst = pDst->ptr<float>(0);
float p0 = 0.f, i0 = 0.f;
uint channel = pReal->channels();
for (int u = 0; u < pReal->rows; u++)
{
for (int v = 0; v < pReal->cols; v++)
{
p0 = *real, i0 = *imaginary;
*dst = (sqrtf((p0 * p0) + (i0 * i0))) * scale;
real += channel;
imaginary += channel;
dst += channel;
}
}
}
반대로 주파수 영역의 신호를 공간 주파수 영역으로 변환시키는 IDFT 코드입니다. 입력은 pReal, pImaginary 출력은 pDst 입니다.
void FourierTransform::IDFT(Mat* pReal, Mat* pImaginary, Mat* pDst)
{
float* real = pReal->ptr<float>(0);
float* imaginary = pImaginary->ptr<float>(0);
float sumReal = 0.f;
float sumImaginary = 0.f;
float* dst = pDst->ptr<float>(0);
uint channel = pReal->channels();
float N = (float)pReal->rows;
float M = (float)pReal->cols;
float NM = N * M;
float term = 0.f;
float r = 0.f, i = 0.f;
float pixel = 0.f;
for (float x = 0; x < N; x++)
{
for (float y = 0; y < M; y++)
{
real = pReal->ptr<float>(0);
imaginary = pImaginary->ptr<float>(0);
sumReal = 0.f;
sumImaginary = 0.f;
for (float u = 0; u < N; u++)
{
for (float v = 0; v < M; v++)
{
term = 2 * PI * ((u * x / N) + (v * y / M));
r = *real;
i = *imaginary;
sumReal += r * cosf(term) - i * sinf(term);
sumImaginary += r * sinf(term) + i * cosf(term);
real += channel;
imaginary += channel;
}
}
pixel = sqrtf((sumReal) * (sumReal)+(sumImaginary) * (sumImaginary));
if (pixel < 0) pixel = 0.f;
if (pixel > 1) pixel = 1.f;
*dst = pixel;
sumReal += channel;
sumImaginary += channel;
dst += channel;
}
}
}
'영상처리(DigitalImageProcessing)' 카테고리의 다른 글
FFT(Fast Fourier Transform) (0) | 2021.11.15 |
---|
Comments