2 #include "opencv2/imgproc/imgproc_c.h"
3 #include "_latentsvm.h"
4 #include "_lsvm_resizeimg.h"
7 #define max(a,b) (((a) > (b)) ? (a) : (b))
11 #define min(a,b) (((a) < (b)) ? (a) : (b))
15 // Getting feature map for the selected subimage
18 // int getFeatureMaps(const IplImage * image, const int k, featureMap **map);
20 // image - selected subimage
27 int getFeatureMaps(const IplImage* image, const int k, CvLSVMFeatureMap **map)
30 int p, px, stringSize;
31 int height, width, numChannels;
32 int i, j, kk, c, ii, jj, d;
33 float * datadx, * datady;
36 float magnitude, x, y, tx, ty;
42 float kernel[3] = {-1.f, 0.f, 1.f};
43 CvMat kernel_dx = cvMat(1, 3, CV_32F, kernel);
44 CvMat kernel_dy = cvMat(3, 1, CV_32F, kernel);
49 float boundary_x[NUM_SECTOR + 1];
50 float boundary_y[NUM_SECTOR + 1];
54 height = image->height;
55 width = image->width ;
57 numChannels = image->nChannels;
59 dx = cvCreateImage(cvSize(image->width, image->height),
61 dy = cvCreateImage(cvSize(image->width, image->height),
68 stringSize = sizeX * p;
69 allocFeatureMapObject(map, sizeX, sizeY, p);
71 cvFilter2D(image, dx, &kernel_dx, cvPoint(-1, 0));
72 cvFilter2D(image, dy, &kernel_dy, cvPoint(0, -1));
75 for(i = 0; i <= NUM_SECTOR; i++)
77 arg_vector = ( (float) i ) * ( (float)(PI) / (float)(NUM_SECTOR) );
78 boundary_x[i] = cosf(arg_vector);
79 boundary_y[i] = sinf(arg_vector);
80 }/*for(i = 0; i <= NUM_SECTOR; i++) */
82 r = (float *)malloc( sizeof(float) * (width * height));
83 alfa = (int *)malloc( sizeof(int ) * (width * height * 2));
85 for(j = 1; j < height - 1; j++)
87 datadx = (float*)(dx->imageData + dx->widthStep * j);
88 datady = (float*)(dy->imageData + dy->widthStep * j);
89 for(i = 1; i < width - 1; i++)
92 x = (datadx[i * numChannels + c]);
93 y = (datady[i * numChannels + c]);
95 r[j * width + i] =sqrtf(x * x + y * y);
96 for(ch = 1; ch < numChannels; ch++)
98 tx = (datadx[i * numChannels + ch]);
99 ty = (datady[i * numChannels + ch]);
100 magnitude = sqrtf(tx * tx + ty * ty);
101 if(magnitude > r[j * width + i])
103 r[j * width + i] = magnitude;
108 }/*for(ch = 1; ch < numChannels; ch++)*/
110 max = boundary_x[0] * x + boundary_y[0] * y;
112 for (kk = 0; kk < NUM_SECTOR; kk++)
114 dotProd = boundary_x[kk] * x + boundary_y[kk] * y;
125 maxi = kk + NUM_SECTOR;
129 alfa[j * width * 2 + i * 2 ] = maxi % NUM_SECTOR;
130 alfa[j * width * 2 + i * 2 + 1] = maxi;
131 }/*for(i = 0; i < width; i++)*/
132 }/*for(j = 0; j < height; j++)*/
134 nearest = (int *)malloc(sizeof(int ) * k);
135 w = (float*)malloc(sizeof(float) * (k * 2));
137 for(i = 0; i < k / 2; i++)
140 }/*for(i = 0; i < k / 2; i++)*/
141 for(i = k / 2; i < k; i++)
144 }/*for(i = k / 2; i < k; i++)*/
146 for(j = 0; j < k / 2; j++)
148 b_x = k / 2 + j + 0.5f;
149 a_x = k / 2 - j - 0.5f;
150 w[j * 2 ] = 1.0f/a_x * ((a_x * b_x) / ( a_x + b_x));
151 w[j * 2 + 1] = 1.0f/b_x * ((a_x * b_x) / ( a_x + b_x));
152 }/*for(j = 0; j < k / 2; j++)*/
153 for(j = k / 2; j < k; j++)
155 a_x = j - k / 2 + 0.5f;
156 b_x =-j + k / 2 - 0.5f + k;
157 w[j * 2 ] = 1.0f/a_x * ((a_x * b_x) / ( a_x + b_x));
158 w[j * 2 + 1] = 1.0f/b_x * ((a_x * b_x) / ( a_x + b_x));
159 }/*for(j = k / 2; j < k; j++)*/
162 for(i = 0; i < sizeY; i++)
164 for(j = 0; j < sizeX; j++)
166 for(ii = 0; ii < k; ii++)
168 for(jj = 0; jj < k; jj++)
170 if ((i * k + ii > 0) &&
171 (i * k + ii < height - 1) &&
173 (j * k + jj < width - 1))
175 d = (k * i + ii) * width + (j * k + jj);
176 (*map)->map[ i * stringSize + j * (*map)->numFeatures + alfa[d * 2 ]] +=
177 r[d] * w[ii * 2] * w[jj * 2];
178 (*map)->map[ i * stringSize + j * (*map)->numFeatures + alfa[d * 2 + 1] + NUM_SECTOR] +=
179 r[d] * w[ii * 2] * w[jj * 2];
180 if ((i + nearest[ii] >= 0) &&
181 (i + nearest[ii] <= sizeY - 1))
183 (*map)->map[(i + nearest[ii]) * stringSize + j * (*map)->numFeatures + alfa[d * 2 ] ] +=
184 r[d] * w[ii * 2 + 1] * w[jj * 2 ];
185 (*map)->map[(i + nearest[ii]) * stringSize + j * (*map)->numFeatures + alfa[d * 2 + 1] + NUM_SECTOR] +=
186 r[d] * w[ii * 2 + 1] * w[jj * 2 ];
188 if ((j + nearest[jj] >= 0) &&
189 (j + nearest[jj] <= sizeX - 1))
191 (*map)->map[i * stringSize + (j + nearest[jj]) * (*map)->numFeatures + alfa[d * 2 ] ] +=
192 r[d] * w[ii * 2] * w[jj * 2 + 1];
193 (*map)->map[i * stringSize + (j + nearest[jj]) * (*map)->numFeatures + alfa[d * 2 + 1] + NUM_SECTOR] +=
194 r[d] * w[ii * 2] * w[jj * 2 + 1];
196 if ((i + nearest[ii] >= 0) &&
197 (i + nearest[ii] <= sizeY - 1) &&
198 (j + nearest[jj] >= 0) &&
199 (j + nearest[jj] <= sizeX - 1))
201 (*map)->map[(i + nearest[ii]) * stringSize + (j + nearest[jj]) * (*map)->numFeatures + alfa[d * 2 ] ] +=
202 r[d] * w[ii * 2 + 1] * w[jj * 2 + 1];
203 (*map)->map[(i + nearest[ii]) * stringSize + (j + nearest[jj]) * (*map)->numFeatures + alfa[d * 2 + 1] + NUM_SECTOR] +=
204 r[d] * w[ii * 2 + 1] * w[jj * 2 + 1];
207 }/*for(jj = 0; jj < k; jj++)*/
208 }/*for(ii = 0; ii < k; ii++)*/
209 }/*for(j = 1; j < sizeX - 1; j++)*/
210 }/*for(i = 1; i < sizeY - 1; i++)*/
222 return LATENT_SVM_OK;
226 // Feature map Normalization and Truncation
229 // int normalizeAndTruncate(featureMap *map, const float alfa);
232 // alfa - truncation threshold
234 // map - truncated and normalized feature map
238 int normalizeAndTruncate(CvLSVMFeatureMap *map, const float alfa)
241 int sizeX, sizeY, p, pos, pp, xp, pos1, pos2;
242 float * partOfNorm; // norm of C(i, j)
248 partOfNorm = (float *)malloc (sizeof(float) * (sizeX * sizeY));
252 pp = NUM_SECTOR * 12;
254 for(i = 0; i < sizeX * sizeY; i++)
257 pos = i * map->numFeatures;
258 for(j = 0; j < p; j++)
260 valOfNorm += map->map[pos + j] * map->map[pos + j];
261 }/*for(j = 0; j < p; j++)*/
262 partOfNorm[i] = valOfNorm;
263 }/*for(i = 0; i < sizeX * sizeY; i++)*/
268 newData = (float *)malloc (sizeof(float) * (sizeX * sizeY * pp));
270 for(i = 1; i <= sizeY; i++)
272 for(j = 1; j <= sizeX; j++)
275 partOfNorm[(i )*(sizeX + 2) + (j )] +
276 partOfNorm[(i )*(sizeX + 2) + (j + 1)] +
277 partOfNorm[(i + 1)*(sizeX + 2) + (j )] +
278 partOfNorm[(i + 1)*(sizeX + 2) + (j + 1)]) + FLT_EPSILON;
279 pos1 = (i ) * (sizeX + 2) * xp + (j ) * xp;
280 pos2 = (i-1) * (sizeX ) * pp + (j-1) * pp;
281 for(ii = 0; ii < p; ii++)
283 newData[pos2 + ii ] = map->map[pos1 + ii ] / valOfNorm;
284 }/*for(ii = 0; ii < p; ii++)*/
285 for(ii = 0; ii < 2 * p; ii++)
287 newData[pos2 + ii + p * 4] = map->map[pos1 + ii + p] / valOfNorm;
288 }/*for(ii = 0; ii < 2 * p; ii++)*/
290 partOfNorm[(i )*(sizeX + 2) + (j )] +
291 partOfNorm[(i )*(sizeX + 2) + (j + 1)] +
292 partOfNorm[(i - 1)*(sizeX + 2) + (j )] +
293 partOfNorm[(i - 1)*(sizeX + 2) + (j + 1)]) + FLT_EPSILON;
294 for(ii = 0; ii < p; ii++)
296 newData[pos2 + ii + p ] = map->map[pos1 + ii ] / valOfNorm;
297 }/*for(ii = 0; ii < p; ii++)*/
298 for(ii = 0; ii < 2 * p; ii++)
300 newData[pos2 + ii + p * 6] = map->map[pos1 + ii + p] / valOfNorm;
301 }/*for(ii = 0; ii < 2 * p; ii++)*/
303 partOfNorm[(i )*(sizeX + 2) + (j )] +
304 partOfNorm[(i )*(sizeX + 2) + (j - 1)] +
305 partOfNorm[(i + 1)*(sizeX + 2) + (j )] +
306 partOfNorm[(i + 1)*(sizeX + 2) + (j - 1)]) + FLT_EPSILON;
307 for(ii = 0; ii < p; ii++)
309 newData[pos2 + ii + p * 2] = map->map[pos1 + ii ] / valOfNorm;
310 }/*for(ii = 0; ii < p; ii++)*/
311 for(ii = 0; ii < 2 * p; ii++)
313 newData[pos2 + ii + p * 8] = map->map[pos1 + ii + p] / valOfNorm;
314 }/*for(ii = 0; ii < 2 * p; ii++)*/
316 partOfNorm[(i )*(sizeX + 2) + (j )] +
317 partOfNorm[(i )*(sizeX + 2) + (j - 1)] +
318 partOfNorm[(i - 1)*(sizeX + 2) + (j )] +
319 partOfNorm[(i - 1)*(sizeX + 2) + (j - 1)]) + FLT_EPSILON;
320 for(ii = 0; ii < p; ii++)
322 newData[pos2 + ii + p * 3 ] = map->map[pos1 + ii ] / valOfNorm;
323 }/*for(ii = 0; ii < p; ii++)*/
324 for(ii = 0; ii < 2 * p; ii++)
326 newData[pos2 + ii + p * 10] = map->map[pos1 + ii + p] / valOfNorm;
327 }/*for(ii = 0; ii < 2 * p; ii++)*/
328 }/*for(j = 1; j <= sizeX; j++)*/
329 }/*for(i = 1; i <= sizeY; i++)*/
331 for(i = 0; i < sizeX * sizeY * pp; i++)
333 if(newData [i] > alfa) newData [i] = alfa;
334 }/*for(i = 0; i < sizeX * sizeY * pp; i++)*/
337 map->numFeatures = pp;
346 return LATENT_SVM_OK;
350 // Feature map reduction
351 // In each cell we reduce dimension of the feature vector
352 // according to original paper special procedure
355 // int PCAFeatureMaps(featureMap *map)
363 int PCAFeatureMaps(CvLSVMFeatureMap *map)
366 int sizeX, sizeY, p, pp, xp, yp, pos1, pos2;
373 p = map->numFeatures;
374 pp = NUM_SECTOR * 3 + 4;
378 nx = 1.0f / sqrtf((float)(xp * 2));
379 ny = 1.0f / sqrtf((float)(yp ));
381 newData = (float *)malloc (sizeof(float) * (sizeX * sizeY * pp));
383 for(i = 0; i < sizeY; i++)
385 for(j = 0; j < sizeX; j++)
387 pos1 = ((i)*sizeX + j)*p;
388 pos2 = ((i)*sizeX + j)*pp;
390 for(jj = 0; jj < xp * 2; jj++)
393 for(ii = 0; ii < yp; ii++)
395 val += map->map[pos1 + yp * xp + ii * xp * 2 + jj];
396 }/*for(ii = 0; ii < yp; ii++)*/
397 newData[pos2 + k] = val * ny;
399 }/*for(jj = 0; jj < xp * 2; jj++)*/
400 for(jj = 0; jj < xp; jj++)
403 for(ii = 0; ii < yp; ii++)
405 val += map->map[pos1 + ii * xp + jj];
406 }/*for(ii = 0; ii < yp; ii++)*/
407 newData[pos2 + k] = val * ny;
409 }/*for(jj = 0; jj < xp; jj++)*/
410 for(ii = 0; ii < yp; ii++)
413 for(jj = 0; jj < 2 * xp; jj++)
415 val += map->map[pos1 + yp * xp + ii * xp * 2 + jj];
416 }/*for(jj = 0; jj < xp; jj++)*/
417 newData[pos2 + k] = val * nx;
419 } /*for(ii = 0; ii < yp; ii++)*/
420 }/*for(j = 0; j < sizeX; j++)*/
421 }/*for(i = 0; i < sizeY; i++)*/
424 map->numFeatures = pp;
430 return LATENT_SVM_OK;
434 static int getPathOfFeaturePyramid(IplImage * image,
435 float step, int numStep, int startIndex,
436 int sideLength, CvLSVMFeaturePyramid **maps)
438 CvLSVMFeatureMap *map;
443 for(i = 0; i < numStep; i++)
445 scale = 1.0f / powf(step, (float)i);
446 scaleTmp = resize_opencv (image, scale);
447 getFeatureMaps(scaleTmp, sideLength, &map);
448 normalizeAndTruncate(map, VAL_OF_TRUNCATE);
450 (*maps)->pyramid[startIndex + i] = map;
451 cvReleaseImage(&scaleTmp);
452 }/*for(i = 0; i < numStep; i++)*/
453 return LATENT_SVM_OK;
457 // Getting feature pyramid
460 // int getFeaturePyramid(IplImage * image, const filterObject **all_F,
462 const int lambda, const int k,
463 const int startX, const int startY,
464 const int W, const int H, featurePyramid **maps);
468 // maps - feature maps for all levels
472 int getFeaturePyramid(IplImage * image, CvLSVMFeaturePyramid **maps)
480 if(image->depth == IPL_DEPTH_32F)
486 imgResize = cvCreateImage(cvSize(image->width , image->height) ,
488 cvConvert(image, imgResize);
491 W = imgResize->width;
492 H = imgResize->height;
494 step = powf(2.0f, 1.0f / ((float)LAMBDA));
495 maxNumCells = W / SIDE_LENGTH;
496 if( maxNumCells > H / SIDE_LENGTH )
498 maxNumCells = H / SIDE_LENGTH;
500 numStep = (int)(logf((float) maxNumCells / (5.0f)) / logf( step )) + 1;
502 allocFeaturePyramidObject(maps, numStep + LAMBDA);
504 getPathOfFeaturePyramid(imgResize, step , LAMBDA, 0,
505 SIDE_LENGTH / 2, maps);
506 getPathOfFeaturePyramid(imgResize, step, numStep, LAMBDA,
509 if(image->depth != IPL_DEPTH_32F)
511 cvReleaseImage(&imgResize);
514 return LATENT_SVM_OK;