์ด๋ก
์ค์ธ ์๊ณ ๋ฆฌ์ฆ (Otsu Alhorithm) C์ธ์ด ์ค์ต ์ฝ๋
์ ์ฒด ์ฝ๋ : https://github.com/mcrkgus/Computer-Vision/blob/main/otsu.c
#include <stdio.h>
#include <windows.h>
#pragma warning(disable:4996)
int main() {
FILE* fp;
unsigned char Readbuf[256][256];
unsigned char Writebuf[256][256];
unsigned long histogram[256] = { 0 };
double histogram_n[256] = { 0 };
double histogram_c[256];
float scale = 256 * 256;
fp = fopen("LENA_256x256_8bit.raw", "rb");
for (int i = 0; i < 256; i++)
fread(Readbuf[i], 1, 256, fp);
fclose(fp);
//ํ์คํ ๊ทธ๋จ
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 256; j++) {
histogram[Readbuf[i][j]]++;
}
}
int result, wb, wf, ub, uf, u, max, temp;
result = wb = wf = ub = uf = u = max = temp = 0;
// ์ค์ธ
for (int i = 0; i < 256; i++) {
for (int j = 0; j < i + 1; j++) { // background
wb += histogram[j]; // weight
ub = (double)(ub + j * histogram[i] / wb); // mean
}
for (int j = i + 1; j < 256; j++) { // foreground
wf += histogram[j]; // weight
uf = (double)(uf + j * histogram[j] / wf); // mean
}
u = (wb * ub) + (wf * uf); // total mean
result = wb * wf * (uf - ub) * (uf - ub); //between variance
// result = (wb*(ub-u)*(ub-u)) + (wf*(uf-u)*(uf-u))
if (result > max) {
max = result;
temp = i;
}
}
//์๊ณ๊ฐ T
int T = temp;
printf("T = %d", T);
//์์ ์ด์งํ
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 256; j++) {
if(Readbuf[i][j] > T)
Writebuf[i][j] = 255;
else
Writebuf[i][j] = 0;
}
}
//์์ ์ ์ฅ
fp = fopen("lena.raw", "wb");
for (int i = 0; i < 256; i++)
fwrite(Writebuf[i], 1, 256, fp);
fclose(fp);
return 0;
}
int otsh_threshold = 0;
double inter_class_variance = 0;
double calcBinary[256];
Mat dst; // ์ฌ์ ์ ์ ๊ทํ๋ ํ์คํ ๊ทธ๋จ ํ๋ ฌ
// 0 ~ 256 ์ฌ์ด์ ์๊ณ๊ฐ ๊ตฌํ๊ธฐ
for (int i = 0; i < 256; i++) {
int alpha = 0, beta = 0;
int sum1 = 0, sum2 = 0;
double avg1 = 0, avg2 = 0;
// w0 ๊ณ์ฐ (0 ~ t๊น์ง์ ๋์ ํฉ)
for (int j = 0; j < i; j++)
sum1 += calcBinary[j];
// w1 ๊ณ์ฐ (t + 1 ~ L - 1๊น์ง์ ๋์ ํฉ)
sum2 = dst.rows * dst.cols - sum1;
// w0๊ณผ w1์ ๊ฐ์ค์น ๊ตฌํ๊ธฐ
alpha = (double)sum1 / (double)calcBinary.size();
beta = (double)sum2 / (double)calcBinary.size();
// μ0๊ณผ μ1 ๊ตฌํ๊ธฐ (w0๊ณผ w1์ ํ๊ท )
for (int m = 0; m < i; m++)
avg1 += (double)(m * calcBinary[m]) / (double)sum1;
for (int m = i; m < 256; m++)
avg2 += (double)(m * calcBinary[m]) / (double)sum2;
// v0๊ณผ v1 ๊ตฌํ๊ธฐ (๋ถ์ฐ)
double temp = alpha * beta * pow((avg1 - avg2), 2);
// ๊ฐ์ฅ ํฐ V between(t)๋ฅผ ์๊ณ๊ฐ T๋ก ์ทจํ๋ค.
if (inter_class_variance < temp) {
inter_class_variance = temp;
otsh_threshold = i;
}
}
728x90