#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "imatrix.h"
#include "ETF.h"
#include "stackmem.h"
#ifdef MEMDEBUG
#include "mnemosyne.h"
#endif
extern int debug;
#define round(x) ((int) ((x) + 0.5))
ETF *New_ETF(int i, int j) {
ETF *ETF = (struct ETF *)claim(sizeof(struct ETF)); assert(ETF);
ETF->max_grad = 1.0; /* moving this to the start instead of the end of this code
fixed the bug where ETF->p[0] appeared to be overwritten */
ETF->Nr = i; ETF->Nc = j;
ETF->p = (Vect **)claim((sizeof(struct Vect *)) * ETF->Nr); assert(ETF->p);
for (i = 0; i < ETF->Nr; i++) {
ETF->p[i] = (Vect *)claim((sizeof(struct Vect)) * ETF->Nc); assert(ETF->p[i]);
for (j = 0; j < ETF->Nc; j++) { /* unnecessary but may help find bug */
ETF->p[i][j].tx=0.0; ETF->p[i][j].ty=0.0; ETF->p[i][j].mag=0.0;
}
}
return ETF;
}
void ETF_copy(ETF *this, ETF *s) {
int i, j;
assert(this->Nr == s->Nr);
assert(this->Nc == s->Nc);
for (i = 0; i < s->Nr; i++) {
for (j = 0; j < s->Nc; j++) {
this->p[i][j].tx = s->p[i][j].tx;
this->p[i][j].ty = s->p[i][j].ty;
this->p[i][j].mag = s->p[i][j].mag;
}
}
this->Nr = s->Nr;
this->Nc = s->Nc;
this->max_grad = s->max_grad;
}
#define ETF_getRow(ETF) ((ETF)->Nr)
#define ETF_getCol(ETF) ((ETF)->Nc)
#define GetMaxGrad(ETF) ((ETF)->max_grad)
double ETF_crc(ETF *e) {
int i, j;
double crc = 0.0;
for (i = 0; i < e->Nr; i++) {
for (j = 0; j < e->Nc; j++) {
/*if (i < 16 && j < 8) fprintf(stderr, "%06x ", e->p[i][j]);*/
crc = (crc + e->p[i][j].tx);
crc = (crc + e->p[i][j].ty);
crc = (crc + e->p[i][j].mag);
}
/*if (i < 16) fprintf(stderr, "\n");*/
}
return crc;
}
#include "myvec.h"
#ifdef NEVER
void set(ETF *this, imatrix *image) {
int i, j;
double MAX_VAL = 1020.;
double v[2];
this->max_grad = -1.;
for (i = 1; i < image->Nr - 1; i++) {
for (j = 1; j < image->Nc - 1; j++) {
/* ////////////////////////////////////////////////////////////// */
this->p[i][j].tx = (image->p[i+1][j-1] + 2*(double)image->p[i+1][j] + image->p[i+1][j+1]
- image->p[i-1][j-1] - 2*(double)image->p[i-1][j] - image->p[i-1][j+1]) / MAX_VAL;
this->p[i][j].ty = (image->p[i-1][j+1] + 2*(double)image->p[i][j+1] + image->p[i+1][j+1]
- image->p[i-1][j-1] - 2*(double)image->p[i][j-1] - image->p[i+1][j-1]) / MAX_VAL;
/* /////////////////////////////////////////// */
v[0] = this->p[i][j].tx;
v[1] = this->p[i][j].ty;
this->p[i][j].tx = -v[1];
this->p[i][j].ty = v[0];
/* //////////////////////////////////////////// */
this->p[i][j].mag = sqrt(this->p[i][j].tx * this->p[i][j].tx + this->p[i][j].ty * this->p[i][j].ty);
if (this->p[i][j].mag > this->max_grad) {
this->max_grad = this->p[i][j].mag;
}
}
}
for (i = 1; i <= this->Nr - 2; i++) {
this->p[i][0].tx = this->p[i][1].tx;
this->p[i][0].ty = this->p[i][1].ty;
this->p[i][0].mag = this->p[i][1].mag;
this->p[i][this->Nc - 1].tx = this->p[i][this->Nc - 2].tx;
this->p[i][this->Nc - 1].ty = this->p[i][this->Nc - 2].ty;
this->p[i][this->Nc - 1].mag = this->p[i][this->Nc - 2].mag;
}
for (j = 1; j <= this->Nc - 2; j++) {
this->p[0][j].tx = this->p[1][j].tx;
this->p[0][j].ty = this->p[1][j].ty;
this->p[0][j].mag = this->p[1][j].mag;
this->p[this->Nr - 1][j].tx = this->p[this->Nr - 2][j].tx;
this->p[this->Nr - 1][j].ty = this->p[this->Nr - 2][j].ty;
this->p[this->Nr - 1][j].mag = this->p[this->Nr - 2][j].mag;
}
this->p[0][0].tx = ( this->p[0][1].tx + this->p[1][0].tx ) / 2;
this->p[0][0].ty = ( this->p[0][1].ty + this->p[1][0].ty ) / 2;
this->p[0][0].mag = ( this->p[0][1].mag + this->p[1][0].mag ) / 2;
this->p[0][this->Nc-1].tx = ( this->p[0][this->Nc-2].tx + this->p[1][this->Nc-1].tx ) / 2;
this->p[0][this->Nc-1].ty = ( this->p[0][this->Nc-2].ty + this->p[1][this->Nc-1].ty ) / 2;
this->p[0][this->Nc-1].mag = ( this->p[0][this->Nc-2].mag + this->p[1][this->Nc-1].mag ) / 2;
this->p[this->Nr-1][0].tx = ( this->p[this->Nr-1][1].tx + this->p[this->Nr-2][0].tx ) / 2;
this->p[this->Nr-1][0].ty = ( this->p[this->Nr-1][1].ty + this->p[this->Nr-2][0].ty ) / 2;
this->p[this->Nr-1][0].mag = ( this->p[this->Nr-1][1].mag + this->p[this->Nr-2][0].mag ) / 2;
this->p[this->Nr-1][this->Nc - 1].tx = (this->p[this->Nr - 1][this->Nc - 2].tx + this->p[this->Nr - 2][this->Nc - 1].tx)/2;
this->p[this->Nr-1][this->Nc - 1].ty = (this->p[this->Nr - 1][this->Nc - 2].ty + this->p[this->Nr - 2][this->Nc - 1].ty)/2;
this->p[this->Nr-1][this->Nc - 1].mag= (this->p[this->Nr - 1][this->Nc - 2].mag+this->p[this->Nr - 2][this->Nc - 1].mag)/2;
normalize(this);
}
#endif
void set2(ETF *this, imatrix *image) {
int i, j;
double MAX_VAL = 1020.;
double v[2];
mymatrix *tmp = mymatrix_new(image->Nr, image->Nc);
imatrix *gmag;
if (debug) fprintf(stderr, "this #0: %f\n", ETF_crc(this));
if (debug) fprintf(stderr, "uninit tmp: %f\n", mymatrix_crc(tmp));
this->max_grad = -1.;
for (i = 1; i < image->Nr - 1; i++) {
for (j = 1; j < image->Nc - 1; j++) {
double a,b,c,d,e;
/* ////////////////////////////////////////////////////////////// */
a= this->p[i][j].tx = (image->p[i+1][j-1] + 2*(double)image->p[i+1][j] + image->p[i+1][j+1]
- image->p[i-1][j-1] - 2*(double)image->p[i-1][j] - image->p[i-1][j+1]) / MAX_VAL;
b= this->p[i][j].ty = (image->p[i-1][j+1] + 2*(double)image->p[i][j+1] + image->p[i+1][j+1]
- image->p[i-1][j-1] - 2*(double)image->p[i][j-1] - image->p[i+1][j-1]) / MAX_VAL;
/* /////////////////////////////////////////// */
c= v[0] = this->p[i][j].tx;
d= v[1] = this->p[i][j].ty;
/* //////////////////////////////////////////// */
e= tmp->p[i][j] = sqrt(this->p[i][j].tx * this->p[i][j].tx + this->p[i][j].ty * this->p[i][j].ty);
if (debug) if (i == 319 && j == 109) fprintf(stderr, "abcde: %f %f %f %f %f\n", a,b,c,d,e);
if (tmp->p[i][j] > this->max_grad) {
this->max_grad = tmp->p[i][j];
if (debug) if (i == 319 && j == 109) fprintf(stderr, "max grad[%d][%d] = %f\n", i, j, this->max_grad);
}
}
}
if (debug) fprintf(stderr, "tmp0: %f\n", mymatrix_crc(tmp));
if (debug) fprintf(stderr, "this #1: %f\n", ETF_crc(this));
for (i = 1; i <= this->Nr - 2; i++) {
tmp->p[i][0] = tmp->p[i][1];
tmp->p[i][this->Nc - 1] = tmp->p[i][this->Nc - 2];
}
if (debug) fprintf(stderr, "tmp1: %f\n", mymatrix_crc(tmp));
for (j = 1; j <= this->Nc - 2; j++) {
tmp->p[0][j] = tmp->p[1][j];
tmp->p[this->Nr - 1][j] = tmp->p[this->Nr - 2][j];
}
if (debug) fprintf(stderr, "tmp2: %f\n", mymatrix_crc(tmp));
tmp->p[0][0] = ( tmp->p[0][1] + tmp->p[1][0] ) / 2;
tmp->p[0][this->Nc-1] = ( tmp->p[0][this->Nc-2] + tmp->p[1][this->Nc-1] ) / 2;
tmp->p[this->Nr-1][0] = ( tmp->p[this->Nr-1][1] + tmp->p[this->Nr-2][0] ) / 2;
tmp->p[this->Nr - 1][this->Nc - 1] = ( tmp->p[this->Nr - 1][this->Nc - 2] + tmp->p[this->Nr - 2][this->Nc - 1] ) / 2;
if (debug) fprintf(stderr, "tmp3: %f\n", mymatrix_crc(tmp));
gmag = imatrix_new(this->Nr, this->Nc);
/* normalize the magnitude */
for (i = 0; i < this->Nr; i++) {
for (j = 0; j < this->Nc; j++) {
tmp->p[i][j] /= this->max_grad;
gmag->p[i][j] = round(tmp->p[i][j] * 255.0);
}
}
if (debug) fprintf(stderr, "last tmp: %f\n", mymatrix_crc(tmp));
if (debug) fprintf(stderr, "gmag: %d\n", imatrix_crc(gmag));
if (debug) fprintf(stderr, "v: %f\n", v[0]+v[1]);
for (i = 1; i < this->Nr - 1; i++) {
for (j = 1; j < this->Nc - 1; j++) {
/* ////////////////////////////////////////////////////////////// */
this->p[i][j].tx = (gmag->p[i+1][j-1] + 2*(double)gmag->p[i+1][j] + gmag->p[i+1][j+1]
- gmag->p[i-1][j-1] - 2*(double)gmag->p[i-1][j] - gmag->p[i-1][j+1]) / MAX_VAL;
this->p[i][j].ty = (gmag->p[i-1][j+1] + 2*(double)gmag->p[i][j+1] + gmag->p[i+1][j+1]
- gmag->p[i-1][j-1] - 2*(double)gmag->p[i][j-1] - gmag->p[i+1][j-1]) / MAX_VAL;
/* /////////////////////////////////////////// */
v[0] = this->p[i][j].tx;
v[1] = this->p[i][j].ty;
this->p[i][j].tx = -v[1];
this->p[i][j].ty = v[0];
/* //////////////////////////////////////////// */
this->p[i][j].mag = sqrt(this->p[i][j].tx * this->p[i][j].tx + this->p[i][j].ty * this->p[i][j].ty);
if (this->p[i][j].mag > this->max_grad) {
this->max_grad = this->p[i][j].mag;
}
}
}
for (i = 1; i <= this->Nr - 2; i++) {
this->p[i][0].tx = this->p[i][1].tx;
this->p[i][0].ty = this->p[i][1].ty;
this->p[i][0].mag = this->p[i][1].mag;
this->p[i][this->Nc - 1].tx = this->p[i][this->Nc - 2].tx;
this->p[i][this->Nc - 1].ty = this->p[i][this->Nc - 2].ty;
this->p[i][this->Nc - 1].mag = this->p[i][this->Nc - 2].mag;
}
for (j = 1; j <= this->Nc - 2; j++) {
this->p[0][j].tx = this->p[1][j].tx;
this->p[0][j].ty = this->p[1][j].ty;
this->p[0][j].mag = this->p[1][j].mag;
this->p[this->Nr - 1][j].tx = this->p[this->Nr - 2][j].tx;
this->p[this->Nr - 1][j].ty = this->p[this->Nr - 2][j].ty;
this->p[this->Nr - 1][j].mag = this->p[this->Nr - 2][j].mag;
}
this->p[0][0].tx = ( this->p[0][1].tx + this->p[1][0].tx ) / 2;
this->p[0][0].ty = ( this->p[0][1].ty + this->p[1][0].ty ) / 2;
this->p[0][0].mag = ( this->p[0][1].mag + this->p[1][0].mag ) / 2;
this->p[0][this->Nc-1].tx = ( this->p[0][this->Nc-2].tx + this->p[1][this->Nc-1].tx ) / 2;
this->p[0][this->Nc-1].ty = ( this->p[0][this->Nc-2].ty + this->p[1][this->Nc-1].ty ) / 2;
this->p[0][this->Nc-1].mag = ( this->p[0][this->Nc-2].mag + this->p[1][this->Nc-1].mag ) / 2;
this->p[this->Nr-1][0].tx = ( this->p[this->Nr-1][1].tx + this->p[this->Nr-2][0].tx ) / 2;
this->p[this->Nr-1][0].ty = ( this->p[this->Nr-1][1].ty + this->p[this->Nr-2][0].ty ) / 2;
this->p[this->Nr-1][0].mag = ( this->p[this->Nr-1][1].mag + this->p[this->Nr-2][0].mag ) / 2;
this->p[this->Nr - 1][this->Nc-1].tx = (this->p[this->Nr - 1][this->Nc - 2].tx + this->p[this->Nr - 2][this->Nc - 1].tx)/2;
this->p[this->Nr - 1][this->Nc-1].ty = (this->p[this->Nr - 1][this->Nc - 2].ty + this->p[this->Nr - 2][this->Nc - 1].ty)/2;
this->p[this->Nr - 1][this->Nc-1].mag= (this->p[this->Nr - 1][this->Nc - 2].mag+this->p[this->Nr - 2][this->Nc - 1].mag)/2;
if (debug) fprintf(stderr, "this before norm: %f\n", ETF_crc(this));
normalize(this);
if (debug) fprintf(stderr, "this after norm - returning %f from set2\n", ETF_crc(this));
}
static void make_unit(double *vx, double *vy) {
double mag = sqrt( *vx * *vx + *vy * *vy );
if (mag != 0.0) { *vx /= mag; *vy /= mag; }
}
void normalize(ETF *this) {
int i, j;
for (i = 0; i < this->Nr; i++) {
for (j = 0; j < this->Nc; j++) {
make_unit(&this->p[i][j].tx, &this->p[i][j].ty);
this->p[i][j].mag /= this->max_grad;
}
}
}
void Smooth(ETF *this, int half_w, int M) {
/*int MAX_GRADIENT = -1;*/
int i, j, k;
double weight;
int s, t;
int x, y;
double mag_diff;
double v[2], w[2], g[2];
double angle;
double factor;
int image_x = ETF_getRow(this);
int image_y = ETF_getCol(this);
ETF *e2 = New_ETF(image_x, image_y);
ETF_copy(e2, this);
if (debug) fprintf(stderr, "e2=this -> %f\n", ETF_crc(e2));
for (k = 0; k < M; k++) {
if (debug) fprintf(stderr, "Smooth: k = %d\n", k);
/* ////////////////////// */
/* horizontal*/
for (j = 0; j < image_y; j++) {
for (i = 0; i < image_x; i++) {
g[0] = g[1] = 0.0;
v[0] = this->p[i][j].tx;
v[1] = this->p[i][j].ty;
for (s = -half_w; s <= half_w; s++) {
/* ////////////////////////////////////// */
x = i+s; y = j;
if (x > image_x-1) x = image_x-1;
else if (x < 0) x = 0;
if (y > image_y-1) y = image_y-1;
else if (y < 0) y = 0;
/* ////////////////////////////////////// */
mag_diff = this->p[x][y].mag - this->p[i][j].mag;
/* //////////////////////////////////////////////////// */
w[0] = this->p[x][y].tx;
w[1] = this->p[x][y].ty;
/* ////////////////////////////// */
factor = 1.0;
angle = v[0] * w[0] + v[1] * w[1];
if (angle < 0.0) {
factor = -1.0;
}
weight = mag_diff + 1;
/* //////////////////////////////////////////////////// */
g[0] += weight * this->p[x][y].tx * factor;
g[1] += weight * this->p[x][y].ty * factor;
}
make_unit(&g[0], &g[1]);
e2->p[i][j].tx = g[0];
e2->p[i][j].ty = g[1];
}
}
if (debug) fprintf(stderr, "horizontal loop -> %f\n", ETF_crc(e2));
ETF_copy(this, e2);/* ORDER SWAPPED!*/
/* /////////////////////////////// */
/* vertical */
for (j = 0; j < image_y; j++) {
for (i = 0; i < image_x; i++) {
g[0] = g[1] = 0.0;
v[0] = this->p[i][j].tx;
v[1] = this->p[i][j].ty;
for (t = -half_w; t <= half_w; t++) {
/* ////////////////////////////////////// */
x = i; y = j+t;
if (x > image_x-1) x = image_x-1;
else if (x < 0) x = 0;
if (y > image_y-1) y = image_y-1;
else if (y < 0) y = 0;
/* ////////////////////////////////////// */
mag_diff = this->p[x][y].mag - this->p[i][j].mag;
/* //////////////////////////////////////////////////// */
w[0] = this->p[x][y].tx;
w[1] = this->p[x][y].ty;
/* ////////////////////////////// */
factor = 1.0;
/* ///////////////////////////// */
angle = v[0] * w[0] + v[1] * w[1];
if (angle < 0.0) factor = -1.0;
/* /////////////////////////////////////////////////////// */
weight = mag_diff + 1;
/* //////////////////////////////////////////////////// */
g[0] += weight * this->p[x][y].tx * factor;
g[1] += weight * this->p[x][y].ty * factor;
}
make_unit(&g[0], &g[1]);
e2->p[i][j].tx = g[0];
e2->p[i][j].ty = g[1];
}
}
if (debug) fprintf(stderr, "vertical loop -> %f\n", ETF_crc(e2));
ETF_copy(this, e2);
}
/* ////////////////////////////////////////// */
}