[3b7b62]: ImageMap.c Maximize Restore History

Download this file

ImageMap.c    199 lines (180 with data), 5.0 kB

  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
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/* autopano-sift, Automatic panorama image creation
* Copyright (C) 2004 -- Sebastian Nowozin
*
* This program is free software released under the GNU General Public
* License, which is included in this software package (doc/LICENSE).
*/
/* ImageMap.cs
*
* Abstract floating point image map processing functionality.
*
* (C) Copyright 2004 -- Sebastian Nowozin (nowozin@cs.tu-berlin.de)
*/
#include "AutoPanoSift.h"
ImageMap* ImageMap_new0()
{
ImageMap* self = (ImageMap*)malloc(sizeof(ImageMap));
return self;
}
ImageMap* ImageMap_new(int xDim, int yDim)
{
ImageMap* self = ImageMap_new0();
self->xDim = xDim;
self->yDim = yDim;
self->values = FloatMap_new(xDim, yDim);
return self;
}
void ImageMap_delete(ImageMap* self)
{
if (self) {
if (self->values) {
FloatMap_delete(self->values);
}
free(self);
}
}
ImageMap* ImageMap_clone(ImageMap* self)
{
ImageMap* result = ImageMap_new(self->xDim, self->yDim);
int x;
for(x=0; x<self->xDim; x++) {
memcpy(result->values[x], self->values[x], self->yDim*sizeof(double));
}
return result;
}
void ImageMap_Save(ImageMap* self, char* filename, char* comment)
{
FILE* fp = fopen(filename, "w");
fprintf(fp, "# %d %d\n", self->xDim, self->yDim);
fprintf(fp, "# %s\n", comment);
int x;
int y;
for (y=0; y<self->yDim; y++) {
for (x=0; x<self->xDim; x++) {
fprintf(fp, "%d %d %.15lf\n", y, x, self->values[x][y]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
// Double the size of an imagemap using linear interpolation.
// It is not a real doubling as the last line is omitted (the image size
// would always be odd otherwise and we have no second line for
// interpolation).
ImageMap* ImageMap_ScaleDouble(ImageMap* self)
{
// Doubling an image with x/y dimensions less or equal than 2 will
// result in an image with just (2, 2) dims, so its useless.
if (self->xDim <= 2 || self->yDim <= 2)
return NULL;
ImageMap* result = ImageMap_new(self->xDim * 2 - 2, self->yDim * 2 - 2);
int x;
int y;
for(y=0; y < (self->yDim-1); y++) {
for(x=0; x < (self->xDim-1); x++) {
result->values[x*2+0][y*2+0]=(self->values[x][y]);
result->values[x*2+1][y*2+0]=(self->values[x][y]+self->values[x+1][y])/2.0;
result->values[x*2+0][y*2+1]=(self->values[x][y]+self->values[x][y+1])/2.0;
result->values[x*2+1][y*2+1]=(self->values[x][y]+self->values[x+1][y]+self->values[x][y+1]+self->values[x+1][y+1])/4.0;
}
}
return result;
}
ImageMap* ImageMap_ScaleHalf(ImageMap* self)
{
ImageMap* result = ImageMap_new(self->xDim/2, self->yDim/2);
int x;
int y;
for(y=0; y<result->yDim; y++) {
for(x=0; x<result->xDim; x++) {
#if 1
result->values[x][y]=self->values[2*x ][2*y ];
#else
// 2*x+1 is out of bound!
result->values[x][y]=( self->values[2*x ][2*y ]
+self->values[2*x+1][2*y ]
+self->values[2*x ][2*y+1]
+self->values[2*x+1][2*y+1])/4.0;
#endif
}
}
return result;
}
ImageMap* ImageMap_Add(ImageMap* f1, ImageMap* f2)
{
if (f1->xDim != f2->xDim || f1->yDim != f2->yDim) {
FatalError("Mismatching dimensions");
}
ImageMap* result = ImageMap_new(f1->xDim, f1->yDim);
int x;
int y;
for(y=0; y<f1->yDim; y++) {
for(x=0; x<f1->xDim; x++) {
result->values[x][y]=
f1->values[x][y]+f2->values[x][y];
}
}
return result;
}
ImageMap* ImageMap_Sub(ImageMap* f1, ImageMap* f2)
{
if (f1->xDim != f2->xDim || f1->yDim != f2->yDim) {
FatalError("Mismatching dimensions");
}
ImageMap* result = ImageMap_new(f1->xDim, f1->yDim);
int x;
int y;
for(y=0; y<f1->yDim; y++) {
for(x=0; x<f1->xDim; x++) {
result->values[x][y]=
f1->values[x][y]-f2->values[x][y];
}
}
return result;
}
ImageMap* ImageMap_Mul(ImageMap* f1, ImageMap* f2)
{
if (f1->xDim != f2->xDim || f1->yDim != f2->yDim) {
FatalError("Mismatching dimensions");
}
ImageMap* result = ImageMap_new(f1->xDim, f1->yDim);
int x;
int y;
for(y=0; y<f1->yDim; y++) {
for(x=0; x<f1->xDim; x++) {
result->values[x][y]=
f1->values[x][y]*f2->values[x][y];
}
}
return result;
}
// Normalize: Find the minimum to maximum range, then stretch and limit
// those to exactly 0.0 to 1.0. If both the minimum and maximum values are
// equal, no normalization takes place.
void ImageMap_Normalize(ImageMap* self)
{
int x;
int y;
double min=self->values[0][0];
double max=self->values[0][0];
for(y=0; y<self->yDim; y++) {
for(x=0; x<self->xDim; x++) {
if (min>self->values[x][y]) min = self->values[x][y];
if (max<self->values[x][y]) max = self->values[x][y];
}
}
if (min == max) return;
double diff = max-min;
for(y=0; y<self->yDim; y++) {
for(x=0; x<self->xDim; x++) {
self->values[x][y] = (self->values[x][y]-min) / diff;
}
}
}
ImageMap* ImageMap_GaussianConvolution(ImageMap* self, double sigma)
{
GaussianConvolution* conv = GaussianConvolution_new1(sigma);
ImageMap* result = GaussianConvolution_Convolve(conv, self);
GaussianConvolution_delete(conv);
return result;
}