You are on page 1of 25

#include <avr/pgmspace.

h>
#include "coe.h"
#define W_PAD 14
#define H_PAD 11
#define W
#define H

10
7

#define Patch 3
unsigned int Padding_Red[154];
unsigned int Padding_Green[154];
unsigned int Padding_Blue[154];
unsigned int dark_channel[70];
unsigned int before_sorting[70];
unsigned char indices[70];
unsigned int atm_red = 0;
unsigned int atm_green = 0;
unsigned int atm_blue = 0;
unsigned int T_Map_Red[70];
unsigned int T_Map_Green[70];
unsigned int T_Map_Blue[70];
unsigned int Trans_Map[70];
int Refine_Trans_Map[70];
/*
unsigned char TMap_Padding_Red[154];
unsigned char TMap_Padding_Green[154];
unsigned char TMap_Padding_Blue[154];
*/
// cum sum like cumsum in matlab
void CumSum(unsigned int *src,unsigned int *dest,unsigned char Height,unsigned c
har Width,unsigned char d)
{
unsigned char save_add = 0,new_add = 0;
// Height = 4, Width = 5
if(d == 1) {
// summation over column
for( int y = 0; y < Height; y ++ ) {
for(int x = 0; x < Width; x++) {
save_add = (y*Width) + x;
if(y > 0) {
new_add = ((y-1)*Width) + x;
dest[save_add] = dest[new_add] + src[save_add];
}
else
dest[save_add] = (unsigned int)src[x];
}
}
}
else {
// summation over row

for( int y = 0; y < Height; y ++ ) {


for( int x = 0; x < Width; x ++ ) {
if(y > 0) {
Height = 5;
Width = 4;
save_add = ((y-1)*Width)+x+y;
dest[save_add] = dest[save_add-1] + src[save_add];
}
else
dest[x*Width] = src[x*Width];
}
}
}
}
// cum sum like cumsum in matlab
void CumSum_Signed(int *src,int *dest,unsigned char Height,unsigned char Width,u
nsigned char d)
{
unsigned char save_add = 0,new_add = 0;
// Height = 4, Width = 5
if(d == 1) {
// summation over column
for( int y = 0; y < Height; y ++ ) {
for(int x = 0; x < Width; x++) {
save_add = (y*Width) + x;
if(y > 0) {
new_add = ((y-1)*Width) + x;
dest[save_add] = dest[new_add] + src[save_add];
}
else
dest[save_add] = (unsigned int)src[x];
}
}
}
else {
// summation over row
for( int y = 0; y < Height; y ++ ) {
for( int x = 0; x < Width; x ++ ) {
if(y > 0) {
Height = 5;
Width = 4;
save_add = ((y-1)*Width)+x+y;
dest[save_add] = dest[save_add-1] + src[save_add];
}
else
dest[x*Width] = src[x*Width];
}
}
}
}
void boxfilter(unsigned int *imSrc, unsigned int* imDst,unsigned char r) {
unsigned char Height = 4, Width = 5;

unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

int imCum[Height*Width];
int row1[Width];
int row4[Width];
int col1[Height*2];
int col4[Height*2];
char add_src,add_dest;
char index = 0;

// Height = 4, Width = 5
memset(imCum,0,sizeof(imCum));
memset(imDst,0,sizeof(imDst));
memset(row1,0,sizeof(row1));
memset(row4,0,sizeof(row4));
memset(col1,0,sizeof(col1));
memset(col4,0,sizeof(col4));
CumSum(imSrc,imCum,Height,Width,1);
for(int x=r; x<=(2*r); x++) {
for(int y=0; y<Width; y++) {
add_src = (x*Width) + y;
add_dest = ((x-1)*Width) + y;
imDst[add_dest] = imCum[add_src];
}
}
for(int x=((2*r)+1); x<Height ; x++) {
for(int y=0; y<Width; y++) {
add_src = (x*Width) + y;
row4[y] = imCum[add_src];
row1[y] = imCum[y];
imDst[((r+1)*Width)+y] = (row4[y] - row1[y]);
}
}
for(int x=0; x<1 ; x++) {
for(int y=0; y<Width; y++) {
add_src = ((x+3)*Width)+y;
add_dest = ((x+1)*Width)+y;
row4[y] = imCum[add_src];
row1[y] = imCum[add_dest];
imDst[add_src] = (row4[y] - row1[y]);
}
}
CumSum(imDst,imCum,Height,Width,2);
for(int x=0; x<Height; x++) {
for(int y=r; y<=(2*r); y++) {
add_src = (x*Width) + y;
add_dest = (x*Width) + (y-r);
imDst[add_dest] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=(2*r)+1; y<Width; y++) {

add_src = (x*Width) + y;
col4[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=0; y<Width-3; y++) {
add_src = (x*Width) + y;
col1[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=(2*r); y<Width-1; y++) {
add_dest = (x*Width) + y;
imDst[add_dest] = (col4[index] - col1[index]);
index++;
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=Width-1; y<Width; y++) {
add_src = (x*Width) + y;
col4[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=Width-3; y<Width-r-1; y++) {
add_src = (x*Width) + y;
col1[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=Width-1; y<Width; y++) {
add_dest = (x*Width) + y;
imDst[add_dest] = (col4[index] - col1[index]);
index++;
}
}
}
void boxfilter_signed(int *imSrc, int* imDst,unsigned char r) {
unsigned char Height = 4, Width = 5;
int imCum[Height*Width];
unsigned int row1[Width];
unsigned int row4[Width];
unsigned int col1[Height*2];
unsigned int col4[Height*2];
unsigned char add_src,add_dest;
unsigned char index = 0;
// Height = 4, Width = 5

memset(imCum,0,sizeof(imCum));
memset(imDst,0,sizeof(imDst));
memset(row1,0,sizeof(row1));
memset(row4,0,sizeof(row4));
memset(col1,0,sizeof(col1));
memset(col4,0,sizeof(col4));
CumSum_Signed(imSrc,imCum,Height,Width,1);
for(int x=r; x<=(2*r); x++) {
for(int y=0; y<Width; y++) {
add_src = (x*Width) + y;
add_dest = ((x-1)*Width) + y;
imDst[add_dest] = imCum[add_src];
}
}
for(int x=((2*r)+1); x<Height ; x++) {
for(int y=0; y<Width; y++) {
add_src = (x*Width) + y;
row4[y] = imCum[add_src];
row1[y] = imCum[y];
imDst[((r+1)*Width)+y] = (row4[y] - row1[y]);
}
}
for(int x=0; x<1 ; x++) {
for(int y=0; y<Width; y++) {
add_src = ((x+3)*Width)+y;
add_dest = ((x+1)*Width)+y;
row4[y] = imCum[add_src];
row1[y] = imCum[add_dest];
imDst[add_src] = (row4[y] - row1[y]);
}
}
CumSum_Signed(imDst,imCum,Height,Width,2);
for(int x=0; x<Height; x++) {
for(int y=r; y<=(2*r); y++) {
add_src = (x*Width) + y;
add_dest = (x*Width) + (y-r);
imDst[add_dest] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=(2*r)+1; y<Width; y++) {
add_src = (x*Width) + y;
col4[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=0; y<Width-3; y++) {
add_src = (x*Width) + y;

col1[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=(2*r); y<Width-1; y++) {
add_dest = (x*Width) + y;
imDst[add_dest] = (col4[index] - col1[index]);
index++;
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=Width-1; y<Width; y++) {
add_src = (x*Width) + y;
col4[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=Width-3; y<Width-r-1; y++) {
add_src = (x*Width) + y;
col1[index++] = imCum[add_src];
}
}
index = 0;
for(int x=0; x<Height; x++) {
for(int y=Width-1; y<Width; y++) {
add_dest = (x*Width) + y;
imDst[add_dest] = (col4[index] - col1[index]);
index++;
}
}
}
void calc_dark_channel (unsigned char ctrl) {
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

int pixel_red,pixel_green,pixel_blue;
char min_pixel = 255;
char col_offset = 0;
char offset = 0, offset_row = 0;
char dv_row = 0, dv_col = 0;
char pixel_index = 0;
char address;
char address_dv;

memset(dark_channel,0,sizeof(dark_channel));
for(int image = 1; image <= (H*W) ; image++) {
offset = 0;
min_pixel = 255;
for(int patch_size = 0; patch_size<Patch; patch_size++) {
for(int x=0; x<Patch; x++) {
address = x + offset_row + offset + col_offset;
pixel_red = Padding_Red[address];

pixel_green = Padding_Green[address];
pixel_blue = Padding_Blue[address];
if(pixel_red < min_pixel) min_pixel = pixel_red;
if(pixel_green < min_pixel) min_pixel = pixel_green;
if(pixel_blue < min_pixel) min_pixel = pixel_blue;
}
offset+=W_PAD;
}
col_offset++;
if(ctrl == 0) { // align column wise
dv_row = (image-1)/10;
dv_col = (image-1)%10;
address_dv = dv_row+(dv_col*7);
dark_channel[address_dv] = min_pixel;
}
else dark_channel[pixel_index++] = min_pixel;
if((image % W) == 0) { // on completion of each row
col_offset = 0;
offset_row+= W_PAD;
}
}
/*
if(ctrl == 0)
print_dark_channel(address_dv+1);
else
print_dark_channel(pixel_index);
*/
}
/*
void div_core_dark_channel (void) {
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

char
char
char
char
char
char

pixel_red,pixel_green,pixel_blue;
min_pixel = 255;
col_offset = 0;
offset = 0, offset_row = 0;
pixel_index = 0;
address;

for(int image = 1; image <= (H*W) ; image++) {


offset = 0;
min_pixel = 255;
for(int patch_size = 0; patch_size<Patch; patch_size++) {
for(int x=0; x<Patch; x++) {
address = x + offset_row + offset + col_offset;
pixel_red = Padding_Red[address];
pixel_green = Padding_Green[address];
pixel_blue = Padding_Blue[address];
if(pixel_red < min_pixel) min_pixel = pixel_red;
if(pixel_green < min_pixel) min_pixel = pixel_green;
if(pixel_blue < min_pixel) min_pixel = pixel_blue;
}
offset+=W_PAD;
}

col_offset++;
dark_channel[pixel_index++] = min_pixel;
if((image % W) == 0) { // on completion of each row
col_offset = 0;
offset_row+= W_PAD;
}
}
print_dark_channel(pixel_index);
}
*/
void print_dark_channel(unsigned char pixel_index) {
for(int x=1; x<=pixel_index; x++) {
Serial.print(dark_channel[x-1]); Serial.print(" ");
if((x % W) == 0) Serial.println();
}
}
void calculate_atmospheric_light (void) {
unsigned char address;
int image_row,image_col;
bubble_sort();
for(int x=0;x<8;x++) {
Serial.print(indices[62+x]); Serial.print(" , ");
image_row = indices[62+x]/7;
image_col = indices[62+x]%7;
address = image_row+image_col*10;
Serial.println(address);
atm_red += pgm_read_byte(&BitMap_Red[address]);
atm_green += pgm_read_byte(&BitMap_Green[address]);
atm_blue += pgm_read_byte(&BitMap_Blue[address]);
}
atm_red/=8;
atm_green/=8;
atm_blue/=8;
Serial.println(atm_red);
Serial.println(atm_green);
Serial.println(atm_blue);
}
void bubble_sort (void) {
unsigned char swap;
int n = H*W;
for(int i = 0; i < n; i++) {
// indices[i] = i;
before_sorting[i] = dark_channel[i];
}
/*
Serial.println("Before Sorting");
for (int c = 0 ; c < n ; c++ ) {
Serial.print(dark_channel[c]); Serial.print(" ");
}
Serial.println();
*/

for (int c = 0; c < n-1; c++)


{
for (int d = 0; d < n-1; d++)
{
if (dark_channel[d+1] < dark_channel[d]) // For decreasing order use
{
swap = dark_channel[d];
dark_channel[d] = dark_channel[d+1];
dark_channel[d+1] = swap;
}
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(dark_channel[i] == before_sorting[j]) {
before_sorting[j] = 0;
indices[i] = j;
break;
}
}
}
/*
Serial.println("After Sorting");
for (int c = 0 ; c < n ; c++ ) {
Serial.print(dark_channel[c]); Serial.print(" ");
}
Serial.println();
Serial.println("before Sorting");
for (int c = 0 ; c < n ; c++ ) {
Serial.print(before_sorting[c]); Serial.print(" ");
}
Serial.println();
for (int c = 0 ; c < n ; c++ ) {
Serial.print(indices[c]); Serial.print(" ");
}
Serial.println();
*/
}
void div_atm_image (unsigned char color,unsigned int *T_Map) {
unsigned char T_Map_Q[70],T_Map_F[70];
unsigned char index = 0;
float no;
memset(T_Map_Q,0,sizeof(T_Map_Q));
memset(T_Map_F,0,sizeof(T_Map_F));
for(int x=0; x<(W*H); x++) {
if(color == 1)
no = (pgm_read_byte(&BitMap_Red[x])/(float)atm_red);
else if(color == 2)
no = (pgm_read_byte(&BitMap_Green[x])/(float)atm_green);
else if(color == 3)
no = (pgm_read_byte(&BitMap_Blue[x])/(float)atm_blue);

T_Map_Q[x] = (unsigned char)(no);


T_Map_F[x] = (unsigned char)round(((no - (float)T_Map_Q[x])*255.0));
//if(T_Map_Q[x] == 1) T_Map_F[x] = 0;
T_Map[index++] = ((T_Map_Q[x]*255) + T_Map_F[x]);
}
}
void pad_array_rom (unsigned char color,unsigned int * new_array) {
unsigned char array_index = 0;
unsigned char bit_map_index = 0;
int pad_size = 2;
for(int x=0;x<(H+(pad_size+pad_size));x++) {
for(int y=0;y<(W+(pad_size+pad_size));y++) {
if(x>=0 && x<pad_size)
new_array[array_index++] = 255;
else if(x>=pad_size && x<(H+pad_size)) {
if((y>=0 && y<pad_size) || (y>=(W+pad_size) && y<(W+(pad_size+pad_size))))
new_array[array_index++] = 255;
else {
if(color == 1)
new_array[array_index++] = pgm_read_byte(&BitMap_Red[bit_map_index++]);
else if(color == 2)
new_array[array_index++] = pgm_read_byte(&BitMap_Green[bit_map_index++]);
else if(color == 3)
new_array[array_index++] = pgm_read_byte(&BitMap_Blue[bit_map_index++]);
}
}
else if(x>=(H+pad_size) && x<(H+(pad_size+pad_size)))
new_array[array_index++] = 255;
}
}
}
void pad_array_ram (unsigned char color,unsigned int * new_array) {
unsigned char array_index = 0;
unsigned char bit_map_index = 0;
int pad_size = 2;
for(int x=0;x<(H+(pad_size+pad_size));x++) {
for(int y=0;y<(W+(pad_size+pad_size));y++) {
if(x>=0 && x<pad_size)
new_array[array_index++] = 255;
else if(x>=pad_size && x<(H+pad_size)) {
if((y>=0 && y<pad_size) || (y>=(W+pad_size) && y<(W+(pad_size+pad_size))))
new_array[array_index++] = 255;
else {
if(color == 1)
new_array[array_index++] = T_Map_Red[bit_map_index++];
else if(color == 2)
new_array[array_index++] = T_Map_Green[bit_map_index++];
else if(color == 3)
new_array[array_index++] = T_Map_Blue[bit_map_index++];
}
}
else if(x>=(H+pad_size) && x<(H+(pad_size+pad_size)))
new_array[array_index++] = 255;
}

}
}
void mul_omega (unsigned int * TMap) {
unsigned char T_Map_Q[70],T_Map_F[70];
unsigned char index = 0;
float no;
memset(T_Map_Q,0,sizeof(T_Map_Q));
memset(T_Map_F,0,sizeof(T_Map_F));
// 0.95 = 268
for(int x=0; x<(W*H); x++) {
no = dark_channel[x]/268.0;
T_Map_Q[x] = (unsigned char)(no);
T_Map_F[x] = (unsigned char)round(((no - (float)T_Map_Q[x])*255.0));
//if(T_Map_Q[x] == 1) T_Map_F[x] = 0;
TMap[index++] = 255 - ((T_Map_Q[x]*255) + T_Map_F[x]);
}
}
void Get_Radiance (void){
int image_red[70];
int image_green[70];
int image_blue[70];
char T_Map_Q;
int T_Map_F;
int max_red = 255;
int max_green = 255;
int max_blue = 255;
int maximum;
float no;
memset(image_red,0,sizeof(image_red));
memset(image_green,0,sizeof(image_green));
memset(image_blue,0,sizeof(image_blue));
for(int x=0; x<(W*H); x++) {
image_red[x] = (int)(pgm_read_byte(&BitMap_Red[x]) - atm_red);
image_green[x] = (int)(pgm_read_byte(&BitMap_Green[x]) - atm_green);
image_blue[x] = (int)(pgm_read_byte(&BitMap_Blue[x]) - atm_blue);
}
// max(tMat,t0)
for(int x=0; x<(W*H); x++) {
//
if(Trans_Map[x] < 25) Trans_Map[x] = 25; // with out guided filter
if(Refine_Trans_Map[x] < 25) Refine_Trans_Map[x] = 25;
}
for(int x=0; x<(W*H); x++) {
no = (float)image_red[x]/(float)Refine_Trans_Map[x];
T_Map_Q = (char)(no);

T_Map_F = (int)round(((no - (float)T_Map_Q)*255.0));


image_red[x] = atm_red + ((T_Map_Q*255) + T_Map_F);
if(image_red[x] > max_red) max_red = image_red[x];
no = (float)image_green[x]/(float)Refine_Trans_Map[x];
T_Map_Q = (char)(no);
T_Map_F = (int)round(((no - (float)T_Map_Q)*255.0));
image_green[x] = atm_green + ((T_Map_Q*255) + T_Map_F);
if(image_green[x] > max_green) max_green = image_green[x];
no = (float)image_blue[x]/(float)Refine_Trans_Map[x];
T_Map_Q = (unsigned char)(no);
T_Map_F = (int)round(((no - (float)T_Map_Q)*255.0));
image_blue[x] = atm_blue + ((T_Map_Q*255) + T_Map_F);
if(image_blue[x] > max_blue) max_blue = image_blue[x];
}
// find largest number
if(max_red>=max_green && max_red>=max_blue) maximum = max_red;
if(max_green>=max_red && max_green>=max_blue) maximum = max_green;
if(max_blue>=max_red && max_blue>=max_green) maximum = max_blue;
for(int x=0; x<(W*H); x++) {
no = (float)image_red[x]/(float)maximum;
T_Map_Q = (char)(no);
T_Map_F = (int)round(((no - (float)T_Map_Q)*255.0));
image_red[x] = abs((T_Map_Q*255) + T_Map_F);
no = (float)image_green[x]/(float)maximum;
T_Map_Q = (char)(no);
T_Map_F = (int)round(((no - (float)T_Map_Q)*255.0));
image_green[x] = abs((T_Map_Q*255) + T_Map_F);
no = (float)image_blue[x]/(float)maximum;
T_Map_Q = (unsigned char)(no);
T_Map_F = (int)round(((no - (float)T_Map_Q)*255.0));
image_blue[x] = abs((T_Map_Q*255) + T_Map_F);
}
}
void calculate_dark_channel(void) {
pad_array_rom(1,Padding_Red);
pad_array_rom(2,Padding_Green);
pad_array_rom(3,Padding_Blue);

calc_dark_channel(0);
}
void calculate_transmission_map (void) {
div_atm_image(1,T_Map_Red);
div_atm_image(2,T_Map_Green);
div_atm_image(3,T_Map_Blue);
pad_array_ram(1,Padding_Red);
pad_array_ram(2,Padding_Green);
pad_array_ram(3,Padding_Blue);
calc_dark_channel(1); // align row wise
mul_omega(Trans_Map);
}
void recover_image (void) {
Get_Radiance();
}
void down_sampling(unsigned int*red_sub,unsigned int*green_sub,unsigned int*blue
_sub,unsigned int*sub_p) {
unsigned char pixcel_red[70];
unsigned char pixcel_green[70];
unsigned char pixcel_blue[70];
memset(pixcel_red,0,sizeof(pixcel_red));
memset(pixcel_green,0,sizeof(pixcel_green));
memset(pixcel_blue,0,sizeof(pixcel_blue));
memset(red_sub,0,sizeof(red_sub));
memset(green_sub,0,sizeof(green_sub));
memset(blue_sub,0,sizeof(blue_sub));
memset(sub_p,0,sizeof(sub_p));
for(int x=0; x<70; x++) {
pixcel_red[x] = pgm_read_byte(&BitMap_Red[x]);
pixcel_green[x] = pgm_read_byte(&BitMap_Green[x]);
pixcel_blue[x] = pgm_read_byte(&BitMap_Blue[x]);
}
resizePixels(pixcel_red,pixcel_green,pixcel_blue,red_sub,green_sub,blue_sub,sub_
p,10,7,5,4);
}
void resizePixels(unsigned char* pixels_red,unsigned char* pixels_green,unsigned
char* pixels_blue,unsigned int* red_sub,unsigned int* green_sub,unsigned int* b
lue_sub,unsigned int* p_sub,unsigned char w1,unsigned char h1,unsigned char w2,u
nsigned char h2) {
unsigned char
unsigned char
unsigned char
unsigned char
float no;

row_index[h2];
col_index[w2];
add_rom,add_ram;
T_Map_Q,T_Map_F;

memset(row_index,0,sizeof(row_index));

memset(col_index,0,sizeof(col_index));
// 127.0 = 0.5
for(int x=0;x<h2;x++) {
no = (x+1)/127.0;
T_Map_Q = (unsigned char)(no);
T_Map_F = (unsigned char)round(((no - (float)T_Map_Q)*255.0));
row_index[x] = min(((T_Map_Q*255) + T_Map_F),h1);
}
for(int x=0;x<w2;x++) {
no = (x+1)/127.0;
T_Map_Q = (unsigned char)(no);
T_Map_F = (unsigned char)round(((no - (float)T_Map_Q)*255.0));
col_index[x] = min(((T_Map_Q*255) + T_Map_F),w1);
}
for (int i=0;i<h2;i++) {
for (int j=0;j<w2;j++) {
add_rom = ((row_index[i]-1)*w1) + (col_index[j]-1);
add_ram = (i*w2)+j;
red_sub[add_ram] = (unsigned int)pixels_red[add_rom];
green_sub[add_ram] = (unsigned int)pixels_green[add_rom];
blue_sub[add_ram] = (unsigned int)pixels_blue[add_rom];
p_sub[add_ram] = (unsigned int)Trans_Map[add_rom];
}
}
}
void div_core(unsigned int* dividend,unsigned int* divisor,unsigned int* ans) {
double no;
for(int x=0;x<20;x++) {
no = (double)dividend[x] / (double)divisor[x];
ans[x]= (unsigned int)round(no);
}
}
void div_core_signed (int* dividend,unsigned int* divisor,int* ans) {
double no;
for(int x=0;x<20;x++) {
no = (double)dividend[x] / (double)divisor[x];
ans[x]= (int)round(no);
}
}
void mul_core(unsigned int* multiplicand,unsigned int* multiplier,unsigned int*
ans) {
for(int x=0;x<20;x++) {
ans[x] = (unsigned int)round((multiplicand[x]*multiplier[x])/255.0);
}
}
void mul_core_signed(unsigned int* multiplicand,int* multiplier,int* ans) {
double no;
for(int x=0;x<20;x++) {
no = ((int)multiplicand[x]*(int)multiplier[x])/255.0;

ans[x] = (int)round(no);
}
}
void inv (int* b,int* ans) {
int det1,det2,det3;
int determinant = 0;
float c[9];
int Q,F;
determinant = 0;
for(int i=0;i<3;i++) {
switch (i) {
case 0:
det1 = b[0]*((b[4]*b[8]) - (b[5]*b[7]));
break;
case 1:
det2 = b[1]*((b[5]*b[6]) - (b[3]*b[8]));
break;
case 2:
det3 = b[2]*((b[3]*b[7]) - (b[4]*b[6]));
break;
}
}
determinant = det1 + det2 + det3;
Serial.println(determinant);

//

for(int i=0;i<9;i++) {
switch (i) {
case 0:
c[0] = (((b[4]*b[8])-(b[5]*b[7]))/(float)determinant);
break;
case 1:
c[1] = (((b[7]*b[2])-(b[8]*b[1]))/(float)determinant);
break;
case 2:
c[2] = (((b[1]*b[5])-(b[2]*b[4]))/(float)determinant);
break;
case 3:
c[3] = (((b[5]*b[6])-(b[3]*b[8]))/(float)determinant);
break;
case 4:
c[4] = (((b[8]*b[0])-(b[6]*b[2]))/(float)determinant);
break;
case 5:
c[5] = (((b[2]*b[3])-(b[0]*b[5]))/(float)determinant);
break;
case 6:

c[6] = (((b[3]*b[7])-(b[4]*b[6]))/(float)determinant);
break;
case 7:
c[7] = (((b[6]*b[1])-(b[7]*b[0]))/(float)determinant);
break;
case 8:
c[8] = (((b[0]*b[4])-(b[1]*b[3]))/(float)determinant);
break;
}
}
for(int x=0; x<9;x++) {
Q = (int)(c[x]);
F = round((c[x] - float(Q))*255.0);
ans[x] = (Q*255 + F);
}
}
void triangle(int* x,int* ans,unsigned char lop) {
boolean a,b;
for(int y=0;y<lop;y++) {
a = (-255 <= x[y]) & (x[y] < 0);
b = (0 <= x[y]) & (x[y] <= 255);
ans[y] = ((x[y]+255)*a) + ((255-x[y])*b);
}
}
void x_axis(int* ind,int* wei) {
unsigned char add;
unsigned char add1,add2;
int Q,F;
int x[7];
int u[7];
int left[7];
int scale;
int indices_inter[28];
int weights_inter[28];
int var[28];
int c;
float no;
scale = 446; // 1.75
for(int y=0;y<7;y++)
x[y] = ((y+1)*255);
for(int y=0; y<7; y++) {
no = (float)x[y] / (float)scale;
Q = (int) (no);
F = round((no - float(Q))*255.0);
c = (Q*255 + F);
u[y] = (c + 54);
}
for(int y=0;y<7;y++)
left[y] = (u[y]/255 - 1);

for(int y=0;y<7;y++) {
for(int z=0;z<4;z++) {
add = (y*4) + z;
if(z==0) indices_inter[add] = left[y];
else
indices_inter[add] = indices_inter[add-1] + 1;
}
}
for(int y=0;y<7;y++) {
for(int z=0;z<4;z++) {
add = (y*4) + z;
var[add] = (int)(u[y] - (indices_inter[add]*255));
}
}
triangle(var,weights_inter,28);
// Clamp out-of-range indices; has the effect of replicating end-points.
for(int y=0;y<28;y++) {
if(indices_inter[y] < 1)
indices_inter[y] = 1;
if(indices_inter[y] > 4)
indices_inter[y] = 4;
}
for(int y=0;y<28;y++) {
if(weights_inter[y] == 0)
}

indices_inter[y] = 0;

add1 = 0; add2 = 0;
for(int y=0;y<28;y++) {
if(indices_inter[y] != 0) ind[add1++] = indices_inter[y];
if(weights_inter[y] != 0) wei[add2++] = weights_inter[y];
}
}
void y_axis(int* ind,int* wei) {
unsigned char add;
unsigned char add1,add2;
int Q,F;
int x[10];
int u[10];
int left[10];
int scale;
int indices_inter[40];
int weights_inter[40];
int var[40];
int c;
float no;
scale = 510; // 2
for(int y=0;y<10;y++)
x[y] = ((y+1)*255);
for(int y=0; y<10; y++) {
no = (float)x[y] / (float)scale;
Q = (int) (no);
F = round((no - float(Q))*255.0);
c = (Q*255 + F);
u[y] = (c + 63);
}

for(int y=0; y<10;y++)


left[y] = (u[y]/255 - 1);
for(int y=0;y<10; y++) {
for(int z=0;z<4;z++) {
add = (y*4) + z;
if(z==0) indices_inter[add] = left[y];
else
indices_inter[add] = indices_inter[add-1] + 1;
}
}
for(int y=0;y<10;y++) {
for(int z=0;z<4;z++) {
add = (y*4) + z;
var[add] = (int)(u[y] - (indices_inter[add]*255));
}
}
triangle(var,weights_inter,40);
// Clamp out-of-range indices; has the effect of replicating end-points.
for(int y=0;y<40;y++) {
if(indices_inter[y] < 1)
indices_inter[y] = 1;
if(indices_inter[y] > 5)
indices_inter[y] = 5;
}
for(int y=0;y<40;y++) {
if(weights_inter[y] == 0)
}

indices_inter[y] = 0;

add1 = 0; add2 = 0;
for(int y=0;y<40;y++) {
if(indices_inter[y] != 0) ind[add1++] = indices_inter[y];
if(weights_inter[y] != 0) wei[add2++] = weights_inter[y];
}
}
/*
void imresizemex(int* im,int* ans,int* wei,int* ind,int dim_x,int dim_y,unsigned
char x) {
unsigned char add;
unsigned char v[2];
if(x == 0) {
for(int i = 0 ; i<dim_y ; i++) {
// 5
for(int j = 0 ; j<dim_x ; j++) { // 7
add = (j*2);
v[0] = ind[add] - 1; v[1] = ind[add+1] - 1;
ans[(j*5)+ i] = (wei[add]*im[v[0]*5+i] + wei[add+1]*im[v[1]*5+i])/255;
}
}
}
else {
for(int i = 0 ; i<dim_x ; i++) {
// 7
for(int j = 0 ; j<dim_y ; j++) { // 10
add = (j*2);
v[0] = ind[add] - 1; v[1] = ind[add+1] - 1;
ans[(i*10)+ j] = (wei[add]*im[v[0]+(i*5)] + wei[add+1]*im[v[1]+(i*5)])

/255;
}
}
}
}
*/
// imresizemex(pixels,B,weights_local_x,indices_local_x,7,5,0);
void imresizemex(int* im,int* ans,int* wei,int* ind,int dim_x,int dim_y,unsigned
char x) {
unsigned char add;
unsigned char v[2];
float x1,x2,x3;
if(x == 0) {
for(int i = 0 ; i<dim_y ; i++) {
// 5
for(int j = 0 ; j<dim_x ; j++) { // 7
add = (j*2);
v[0] = ind[add] - 1; v[1] = ind[add+1] - 1;
x1 = (float)wei[add]*(float)im[(v[0]*5)+i];
x2 = (float)wei[add+1]*(float)im[(v[1]*5)+i];
x3 = (x1 + x2)/255.0;
ans[(j*5)+ i] = round(x3);
}
}
}
else {
for(int i = 0 ; i<dim_x ; i++) {
// 7
for(int j = 0 ; j<dim_y ; j++) { // 10
add = (j*2);
v[0] = ind[add] - 1; v[1] = ind[add+1] - 1;
x1 = (float)wei[add]*(float)im[v[0]+(i*5)];
x2 = (float)wei[add+1]*(float)im[v[1]+(i*5)];
x3 = (x1 + x2)/255.0;
ans[(i*10)+ j] = round(x3);
}
}
}
}
void imresize(int* pixels,int* out) {
int indices_local_x[14];
int weights_local_x[14];
int indices_local_y[20];
int weights_local_y[20];
int B[35];
x_axis(indices_local_x,weights_local_x);
y_axis(indices_local_y,weights_local_y);
imresizemex(pixels,B,weights_local_x,indices_local_x,7,5,0);
imresizemex(B,out,weights_local_y,indices_local_y,7,10,1);

}
void fast_guided_filter (void) {
unsigned char Height = 4, Width = 5;
unsigned int red_sub[20];
unsigned int green_sub[20];
unsigned int blue_sub[20];
unsigned int sub_p[20];
unsigned int color[20];
unsigned int var[20];
unsigned int pixels[20];
unsigned int N[20];
unsigned int sub[20];
unsigned int mean_I_r[20],mean_I_g[20],mean_I_b[20],mean_p[20],mean_Ip_r[20],me
an_Ip_g[20],mean_Ip_b[20];
unsigned int product[20];
int cov_Ip_r[20],cov_Ip_g[20],cov_Ip_b[20];
int Sigma[9],cov_Ip[3],I[9],inverse[9],matrix[9];
unsigned int var_I_rr[20],var_I_rg[20],var_I_rb[20],var_I_gg[20],var_I_gb[20],v
ar_I_bb[20];
int a_r[20],a_g[20],a_b[20];
int b[20],b_r[20],b_g[20],b_b[20];
int sub_signed[20];
int out_red[70],out_green[70],out_blue[70],out_mean[70];
int mean[20],mean_r[20],mean_g[20],mean_b[20];
unsigned char add;
// eps = 0.1^2 = 0.01 = 3
for(int x=0; x<20;x++)
pixels[x] = 1;
for(int x=0; x<9;x++) {
if((x%4) == 0) I[x] = 2;
else I[x] = 0;
}
down_sampling(red_sub,green_sub,blue_sub,sub_p);
boxfilter(pixels,N,1);
boxfilter(red_sub,sub,1);
div_core(sub,N,mean_I_r);
boxfilter(green_sub,sub,1);
div_core(sub,N,mean_I_g);
boxfilter(blue_sub,sub,1);
div_core(sub,N,mean_I_b);
boxfilter(sub_p,sub,1);
div_core(sub,N,mean_p);
mul_core(red_sub,sub_p,color);
boxfilter(color,sub,1);
div_core(sub,N,mean_Ip_r);
mul_core(green_sub,sub_p,color);

boxfilter(color,sub,1);
div_core(sub,N,mean_Ip_g);
mul_core(blue_sub,sub_p,color);
boxfilter(color,sub,1);
div_core(sub,N,mean_Ip_b);
mul_core(mean_I_r,mean_p,color);
for(int x=0;x<20;x++)
cov_Ip_r[x] = mean_Ip_r[x] - color[x];
mul_core(mean_I_g,mean_p,color);
for(int x=0;x<20;x++)
cov_Ip_g[x] = mean_Ip_g[x] - color[x];
mul_core(mean_I_b,mean_p,color);
for(int x=0;x<20;x++)
cov_Ip_b[x] = mean_Ip_b[x] - color[x];
// var_I_rr = boxfilter(I_sub(:, :, 1).*I_sub(:, :, 1), r_sub) ./ N - mean_I_r .
* mean_I_r;
mul_core(mean_I_r,mean_I_r,product);
mul_core(red_sub,red_sub,color);
boxfilter(color,sub,1);
div_core(sub,N,var);
for(int x=0;x<20;x++)
var_I_rr[x] = var[x] - product[x];
// var_I_rg = boxfilter(I_sub(:, :, 1).*I_sub(:, :, 2), r_sub) ./ N - mean_I_r .
* mean_I_g;
mul_core(mean_I_r,mean_I_g,product);
mul_core(red_sub,green_sub,color);
boxfilter(color,sub,1);
div_core(sub,N,var);
for(int x=0;x<20;x++)
var_I_rg[x] = var[x] - product[x];
// var_I_rb = boxfilter(I_sub(:, :, 1).*I_sub(:, :, 3), r_sub) ./ N - mean_I_r .
* mean_I_b;
mul_core(mean_I_r,mean_I_b,product);
mul_core(red_sub,blue_sub,color);
boxfilter(color,sub,1);
div_core(sub,N,var);
for(int x=0;x<20;x++)
var_I_rb[x] = var[x] - product[x];
// var_I_gg = boxfilter(I_sub(:, :, 2).*I_sub(:, :, 2), r_sub) ./ N - mean_I_g .
* mean_I_g;
mul_core(mean_I_g,mean_I_g,product);
mul_core(green_sub,green_sub,color);

boxfilter(color,sub,1);
div_core(sub,N,var);
for(int x=0;x<20;x++)
var_I_gg[x] = var[x] - product[x];
// var_I_gb = boxfilter(I_sub(:, :, 2).*I_sub(:, :, 3), r_sub) ./ N - mean_I_g .
* mean_I_b;
mul_core(mean_I_g,mean_I_b,product);
mul_core(green_sub,blue_sub,color);
boxfilter(color,sub,1);
div_core(sub,N,var);
for(int x=0;x<20;x++)
var_I_gb[x] = var[x] - product[x];
// var_I_bb = boxfilter(I_sub(:, :, 3).*I_sub(:, :, 3), r_sub) ./ N - mean_I_b .
* mean_I_b;
mul_core(mean_I_b,mean_I_b,product);
mul_core(blue_sub,blue_sub,color);
boxfilter(color,sub,1);
div_core(sub,N,var);
for(int x=0;x<20;x++)
var_I_bb[x] = var[x] - product[x];
for(int y=0; y<Height; y++) {
for(int x=0; x<Width; x++) {
add = (y*Width) + x;
Sigma[0]
Sigma[1]
Sigma[2]
Sigma[3]
Sigma[4]
Sigma[5]
Sigma[6]
Sigma[7]
Sigma[8]

=
=
=
=
=
=
=
=
=

var_I_rr[add];
var_I_rg[add];
var_I_rb[add];
var_I_rg[add];
var_I_gg[add];
var_I_gb[add];
var_I_rb[add];
var_I_gb[add];
var_I_bb[add];

cov_Ip[0] = cov_Ip_r[add];
cov_Ip[1] = cov_Ip_g[add];
cov_Ip[2] = cov_Ip_b[add];
for(int x=0;x<9;x++)
matrix[x] = Sigma[x]+ I[x];
inv(matrix,inverse);
a_r[add] = (inverse[0]*cov_Ip[0]) + (inverse[1]*cov_Ip[1]) + (inverse[2]*co
v_Ip[2]);
a_g[add] = (inverse[3]*cov_Ip[0]) + (inverse[4]*cov_Ip[1]) + (inverse[5]*co
v_Ip[2]);
a_b[add] = (inverse[6]*cov_Ip[0]) + (inverse[7]*cov_Ip[1]) + (inverse[8]*co
v_Ip[2]);
}
}

// b = mean_p - a_r .* mean_I_r - a_g .* mean_I_g - a_b .* mean_I_b;


mul_core_signed(mean_I_r,a_r,b_r);
mul_core_signed(mean_I_g,a_g,b_g);
mul_core_signed(mean_I_b,a_b,b_b);
for(int x=0;x<20;x++)
b[x] = (mean_p[x] - (b_r[x] + b_g[x] + b_b[x]));
boxfilter_signed(a_r,sub_signed,1);
div_core_signed(sub_signed,N,mean_r);
boxfilter_signed(a_g,sub_signed,1);
div_core_signed(sub_signed,N,mean_g);
boxfilter_signed(a_b,sub_signed,1);
div_core_signed(sub_signed,N,mean_b);
boxfilter_signed(b,sub_signed,1);
div_core_signed(sub_signed,N,mean);
imresize(mean_r,out_red);
imresize(mean_g,out_green);
imresize(mean_b,out_blue);
imresize(mean,out_mean);
for(int x=0 ; x<70; x++) {
float x1,x2,x3,x4;
x1 = (out_red[x]*(int)pgm_read_byte(&BitMap_Red[x]))/255.0;
x2 = (out_green[x]*(int)pgm_read_byte(&BitMap_Green[x]))/255.0;
x3 = (out_blue[x]*(int)pgm_read_byte(&BitMap_Blue[x]))/255.0;
x4 = out_mean[x];
Refine_Trans_Map[x] = (int)(x1 + x2 + x3 + x4);
}
//
//
//
//

q
+
+
+

= mean_a(:, :, 1) .* I(:, :, 1)...


mean_a(:, :, 2) .* I(:, :, 2)...
mean_a(:, :, 3) .* I(:, :, 3)...
mean_b;

}
void test_atm (void) {
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

char in[8] = {47,35,45,46,44,49,42,43};


int atm_red = 0;
int atm_green = 0;
int atm_blue = 0;
char x,y,z,d;
char add = 37;

unsigned char BitMap_Padding_Red[11][14] =


{
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,121,126,149,160,175,210,203,165,142,131,255,255,
255,255,106,118,129,144,178,200,164,131,129,126,255,255,
255,255,104,110,124,136,159,183,161,141,147,146,255,255,

255,255,98,99,130,147,154,177,163,139,143,139,255,255,
255,255,110,112,123,132,149,169,147,127,130,123,255,255,
255,255,111,119,124,129,145,155,133,120,122,116,255,255,
255,255,107,118,128,136,137,139,134,129,123,114,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
unsigned char BitMap_Padding_Green[11][14] =
{
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,117,123,145,158,170,205,196,159,133,123,255,255,
255,255,101,115,127,142,175,195,157,125,123,118,255,255,
255,255,100,106,121,134,156,179,156,135,141,141,255,255,
255,255,92,96,128,143,150,172,158,134,138,133,255,255,
255,255,105,106,119,127,144,163,141,122,124,117,255,255,
255,255,98,108,113,119,134,144,122,109,112,106,255,255,
255,255,84,98,108,116,117,120,115,110,104,95,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
unsigned char BitMap_Padding_Blue[11][14] =
{
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,44,54,84,109,138,183,178,137,100,84,255,255,
255,255,33,48,68,93,142,173,139,103,89,79,255,255,
255,255,37,45,66,86,123,154,136,111,107,103,255,255,
255,255,40,45,80,105,121,150,138,112,108,99,255,255,
255,255,67,70,84,98,124,147,127,103,102,91,255,255,
255,255,66,78,83,92,112,124,104,89,87,79,255,255,
255,255,50,63,73,81,84,87,83,78,72,62,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
for(int x=0;x<8;x++) {
y = (in[x]*add) / 256;
d = in[x] - (y*7);
z = y + 10*d;
atm_red+=BitMap_Padding_Red[d+2][y+2];
atm_green+=BitMap_Padding_Green[d+2][y+2];
atm_blue+=BitMap_Padding_Blue[d+2][y+2];
Serial.print(d); Serial.print(" , "); Serial.println(y);
}
Serial.println(atm_red/8);
Serial.println(atm_green/8);
Serial.println(atm_blue/8);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);

calculate_dark_channel();
calculate_atmospheric_light();
calculate_transmission_map();
fast_guided_filter();
recover_image();
}
void loop() {
// put your main code here, to run repeatedly:
}

You might also like