#include <stdio.h>
#include <float.h>
#include <cstdlib>
#include <string>
#include <opencv2/highgui.hpp>
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <fstream>
void calc_disperse( cv::Mat &src, size_t row, size_t col, size_t *outRow, size_t *outCol, float *avgLight)
{
float disperse[9], maxdisperse = FLT_MAX;
float avglights[9];
int maxRow = 0, maxCol = 0;
memset(disperse, 0, sizeof(disperse));
memset(avglights, 0, sizeof(avglights));
for(int i = row-2; i <= row; i++)
{
if(i < 0 || (i+2) >= src.rows)
{
continue;
}
for(int j = col-2; j <= col; j++)
{
if(j < 0 || (j+2) >= src.cols)
{
continue;
}
float sum = 0.f;
int index = (i-row+2)*3+(j-col+2);
float *pdisperse = &disperse[index];
float *pavg = &avglights[index];
for(int k = i; k < (i+3); k++)
{
unsigned char *pRow = src.ptr<unsigned char>(k);
for(int m = j; m < (j+3); m++)
{
sum += static_cast<float>(*(pRow+m));
}
}
*pavg = sum/9;
for(int k = i; k < (i+3); k++)
{
unsigned char *pRow = src.ptr<unsigned char>(k);
for(int m = j; m < (j+3); m++)
{
*pdisperse += powf((static_cast<float>(*(pRow+m)) - *pavg), 2);
}
}
*pdisperse /= 9;
}
}
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(disperse[3*i+j] < maxdisperse)
{
maxRow = i;
maxCol = j;
}
}
}
*outRow = row-2+maxRow;
*outCol = col-2+maxCol;
*avgLight = avglights[maxRow*3+maxCol];
return;
}
int main(int argc, char* argv[])
{
int w = 0, h = 0;
std::string fileName = argv[1];
int iter = 1;
if(argc > 2)
iter = atoi(argv[2]);
cv::Mat src = cv::imread(fileName, CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat dst ;
dst.create(src.rows, src.cols, CV_8UC1);
cv::Mat dst1 ;
dst1.create(src.rows, src.cols, CV_8UC1);
printf("%d,%d,%d\n", src.rows, src.cols, src.channels());
imwrite("src.bmp", src);
for(int i = 0; i < src.rows; i++)
{
unsigned char *pdst = dst.ptr<unsigned char>(i);
for(int j = 0; j < src.cols; j++, pdst++)
{
size_t outRow, outCols;
float avgLight = 0.f;
calc_disperse( src, i, j, &outRow, &outCols, &avgLight);
*pdst = static_cast<unsigned char>(avgLight);
}
}
if(iter > 1)
{
for(int i = 0; i < iter-1; i++)
{
dst1 = dst.clone();
unsigned char *pdst = dst.ptr<unsigned char>(i);
for(int j = 0; j < src.cols; j++, pdst++)
{
size_t outRow, outCols;
float avgLight = 0.f;
calc_disperse( dst1, i, j, &outRow, &outCols, &avgLight);
*pdst = static_cast<unsigned char>(avgLight);
}
}
}
imwrite("dst.bmp", dst);
return 0;
}