1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
43 //*F///////////////////////////////////////////////////////////////////////////////////////
44 // Name: icvImgToObs_DCT_8u32f_C1R
45 // Purpose: The function takes as input an image and returns the sequnce of observations
46 // to be used with an embedded HMM; Each observation is top-left block of DCT
47 // coefficient matrix.
49 // Parameters: img - pointer to the original image ROI
50 // imgStep - full row width of the image in bytes
51 // roi - width and height of ROI in pixels
52 // obs - pointer to resultant observation vectors
53 // dctSize - size of the block for which DCT is calculated
54 // obsSize - size of top-left block of DCT coeffs matrix, which is treated
55 // as observation. Each observation vector consists of
56 // obsSize.width * obsSize.height floats.
57 // The following conditions should be satisfied:
58 // 0 < objSize.width <= dctSize.width,
59 // 0 < objSize.height <= dctSize.height.
60 // delta - dctBlocks are overlapped and this parameter specifies horizontal
61 // and vertical shift.
63 // CV_NO_ERR or error code
65 // The algorithm is following:
66 // 1. First, number of observation vectors per row and per column are calculated:
68 // Nx = floor((roi.width - dctSize.width + delta.width)/delta.width);
69 // Ny = floor((roi.height - dctSize.height + delta.height)/delta.height);
71 // So, total number of observation vectors is Nx*Ny, and total size of
72 // array obs must be >= Nx*Ny*obsSize.width*obsSize.height*sizeof(float).
73 // 2. Observation vectors are calculated in the following loop
74 // ( actual implementation may be different ), where
75 // I[x1:x2,y1:y2] means block of pixels from source image with
76 // x1 <= x < x2, y1 <= y < y2,
77 // D[x1:x2,y1:y2] means sub matrix of DCT matrix D.
78 // O[x,y] means observation vector that corresponds to position
79 // (x*delta.width,y*delta.height) in the source image
80 // ( all indices are counted from 0 ).
82 // for( y = 0; y < Ny; y++ )
84 // for( x = 0; x < Nx; x++ )
86 // D = DCT(I[x*delta.width : x*delta.width + dctSize.width,
87 // y*delta.height : y*delta.height + dctSize.height]);
88 // O[x,y] = D[0:obsSize.width, 0:obsSize.height];
93 /*comment out the following line to make DCT be calculated in floating-point arithmetics*/
96 /* for integer DCT only */
102 #define DESCALE CV_DESCALE
103 #define SCALE(x) CV_FLT_TO_FIX((x),DCT_SCALE)
105 typedef float work_t;
107 #define DESCALE(x,n) (float)(x)
108 #define SCALE(x) (float)(x)
111 /* calculate dct transform matrix */
112 static void icvCalcDCTMatrix( work_t * cfs, int n );
114 #define MAX_DCT_SIZE 32
116 static CvStatus CV_STDCALL
117 icvImgToObs_DCT_8u32f_C1R( uchar * img, int imgStep, CvSize roi,
118 float *obs, CvSize dctSize,
119 CvSize obsSize, CvSize delta )
121 /* dct transform matrices: horizontal and vertical */
122 work_t tab_x[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
123 work_t tab_y[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
125 /* temporary buffers for dct */
126 work_t temp0[MAX_DCT_SIZE * 4];
127 work_t temp1[MAX_DCT_SIZE * 4];
136 int n1 = dctSize.height, m1 = n1 / 2;
137 int n2 = dctSize.width, m2 = n2 / 2;
140 return CV_NULLPTR_ERR;
142 if( roi.width <= 0 || roi.height <= 0 )
143 return CV_BADSIZE_ERR;
145 if( delta.width <= 0 || delta.height <= 0 )
146 return CV_BADRANGE_ERR;
148 if( obsSize.width <= 0 || dctSize.width < obsSize.width ||
149 obsSize.height <= 0 || dctSize.height < obsSize.height )
150 return CV_BADRANGE_ERR;
152 if( dctSize.width > MAX_DCT_SIZE || dctSize.height > MAX_DCT_SIZE )
153 return CV_BADRANGE_ERR;
155 Nx = (roi.width - dctSize.width + delta.width) / delta.width;
156 Ny = (roi.height - dctSize.height + delta.height) / delta.height;
158 if( Nx <= 0 || Ny <= 0 )
159 return CV_BADRANGE_ERR;
161 buffer = (work_t *)cvAlloc( roi.width * obsSize.height * sizeof( buffer[0] ));
163 return CV_OUTOFMEM_ERR;
165 icvCalcDCTMatrix( tab_x, dctSize.width );
166 icvCalcDCTMatrix( tab_y, dctSize.height );
168 buf_limit = buffer + obsSize.height * roi.width;
170 for( y = 0; y < Ny; y++, img += delta.height * imgStep )
175 /* do transfroms for each column. Calc only first obsSize.height DCT coefficients */
176 for( x = 0; x < roi.width; x++ )
179 work_t *buf = buffer + x;
180 work_t *tab = tab_y + 2;
184 is = img[x + m1 * imgStep];
185 k0 = ((work_t) is) * tab[-1];
188 /* first coefficient */
189 for( j = 0; j < m1; j++ )
191 float t0 = img[x + j * imgStep];
192 float t1 = img[x + (n1 - 1 - j) * imgStep];
196 temp0[j] = (work_t) t2;
198 temp1[j] = (work_t) t0;
201 buf[0] = DESCALE( is * tab[-2], PASS1_SHIFT );
202 if( (buf += roi.width) >= buf_limit )
205 /* other coefficients */
210 for( k = 0; k < m1; k++ )
211 s += temp1[k] * tab[k];
213 buf[0] = DESCALE( s, PASS1_SHIFT );
214 if( (buf += roi.width) >= buf_limit )
225 for( k = 0; k < m1; k++ )
226 s += temp0[k] * tab[k];
228 buf[0] = DESCALE( s, PASS1_SHIFT );
231 if( (buf += roi.width) >= buf_limit )
238 /* do transforms for rows. */
239 for( x = 0; x + dctSize.width <= roi.width; x += delta.width )
241 for( i = 0; i < obsSize.height; i++ )
243 work_t *buf = buffer + x + roi.width * i;
244 work_t *tab = tab_x + 2;
245 float *obs_limit = obs + obsSize.width;
252 k0 = (work_t) (s * tab[-1]);
255 /* first coefficient */
256 for( j = 0; j < m2; j++ )
259 work_t t1 = buf[n2 - 1 - j];
263 temp0[j] = (work_t) t2;
265 temp1[j] = (work_t) t0;
268 *obs++ = (float) DESCALE( s * tab[-2], PASS2_SHIFT );
270 if( obs == obs_limit )
273 /* other coefficients */
278 for( k = 0; k < m2; k++ )
279 s += temp1[k] * tab[k];
281 obs[0] = (float) DESCALE( s, PASS2_SHIFT );
282 if( ++obs == obs_limit )
294 for( k = 0; k < m2; k++ )
295 s += temp0[k] * tab[k];
296 obs[0] = (float) DESCALE( s, PASS2_SHIFT );
299 if( ++obs == obs_limit )
311 static CvStatus CV_STDCALL
312 icvImgToObs_DCT_32f_C1R( float * img, int imgStep, CvSize roi,
313 float *obs, CvSize dctSize,
314 CvSize obsSize, CvSize delta )
316 /* dct transform matrices: horizontal and vertical */
317 work_t tab_x[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
318 work_t tab_y[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
320 /* temporary buffers for dct */
321 work_t temp0[MAX_DCT_SIZE * 4];
322 work_t temp1[MAX_DCT_SIZE * 4];
331 int n1 = dctSize.height, m1 = n1 / 2;
332 int n2 = dctSize.width, m2 = n2 / 2;
335 return CV_NULLPTR_ERR;
337 if( roi.width <= 0 || roi.height <= 0 )
338 return CV_BADSIZE_ERR;
340 if( delta.width <= 0 || delta.height <= 0 )
341 return CV_BADRANGE_ERR;
343 if( obsSize.width <= 0 || dctSize.width < obsSize.width ||
344 obsSize.height <= 0 || dctSize.height < obsSize.height )
345 return CV_BADRANGE_ERR;
347 if( dctSize.width > MAX_DCT_SIZE || dctSize.height > MAX_DCT_SIZE )
348 return CV_BADRANGE_ERR;
350 Nx = (roi.width - dctSize.width + delta.width) / delta.width;
351 Ny = (roi.height - dctSize.height + delta.height) / delta.height;
353 if( Nx <= 0 || Ny <= 0 )
354 return CV_BADRANGE_ERR;
356 buffer = (work_t *)cvAlloc( roi.width * obsSize.height * sizeof( buffer[0] ));
358 return CV_OUTOFMEM_ERR;
360 icvCalcDCTMatrix( tab_x, dctSize.width );
361 icvCalcDCTMatrix( tab_y, dctSize.height );
363 buf_limit = buffer + obsSize.height * roi.width;
365 imgStep /= sizeof(img[0]);
367 for( y = 0; y < Ny; y++, img += delta.height * imgStep )
372 /* do transfroms for each column. Calc only first obsSize.height DCT coefficients */
373 for( x = 0; x < roi.width; x++ )
376 work_t *buf = buffer + x;
377 work_t *tab = tab_y + 2;
381 is = img[x + m1 * imgStep];
382 k0 = ((work_t) is) * tab[-1];
385 /* first coefficient */
386 for( j = 0; j < m1; j++ )
388 float t0 = img[x + j * imgStep];
389 float t1 = img[x + (n1 - 1 - j) * imgStep];
393 temp0[j] = (work_t) t2;
395 temp1[j] = (work_t) t0;
398 buf[0] = DESCALE( is * tab[-2], PASS1_SHIFT );
399 if( (buf += roi.width) >= buf_limit )
402 /* other coefficients */
407 for( k = 0; k < m1; k++ )
408 s += temp1[k] * tab[k];
410 buf[0] = DESCALE( s, PASS1_SHIFT );
411 if( (buf += roi.width) >= buf_limit )
422 for( k = 0; k < m1; k++ )
423 s += temp0[k] * tab[k];
425 buf[0] = DESCALE( s, PASS1_SHIFT );
428 if( (buf += roi.width) >= buf_limit )
435 /* do transforms for rows. */
436 for( x = 0; x + dctSize.width <= roi.width; x += delta.width )
438 for( i = 0; i < obsSize.height; i++ )
440 work_t *buf = buffer + x + roi.width * i;
441 work_t *tab = tab_x + 2;
442 float *obs_limit = obs + obsSize.width;
449 k0 = (work_t) (s * tab[-1]);
452 /* first coefficient */
453 for( j = 0; j < m2; j++ )
456 work_t t1 = buf[n2 - 1 - j];
460 temp0[j] = (work_t) t2;
462 temp1[j] = (work_t) t0;
465 *obs++ = (float) DESCALE( s * tab[-2], PASS2_SHIFT );
467 if( obs == obs_limit )
470 /* other coefficients */
475 for( k = 0; k < m2; k++ )
476 s += temp1[k] * tab[k];
478 obs[0] = (float) DESCALE( s, PASS2_SHIFT );
479 if( ++obs == obs_limit )
491 for( k = 0; k < m2; k++ )
492 s += temp0[k] * tab[k];
493 obs[0] = (float) DESCALE( s, PASS2_SHIFT );
496 if( ++obs == obs_limit )
509 icvCalcDCTMatrix( work_t * cfs, int n )
511 static const double sqrt2 = 1.4142135623730950488016887242097;
512 static const double pi = 3.1415926535897932384626433832795;
514 static const double sincos[16 * 2] = {
515 1.00000000000000000, 0.00000000000000006,
516 0.70710678118654746, 0.70710678118654757,
517 0.49999999999999994, 0.86602540378443871,
518 0.38268343236508978, 0.92387953251128674,
519 0.30901699437494740, 0.95105651629515353,
520 0.25881904510252074, 0.96592582628906831,
521 0.22252093395631439, 0.97492791218182362,
522 0.19509032201612825, 0.98078528040323043,
523 0.17364817766693033, 0.98480775301220802,
524 0.15643446504023087, 0.98768834059513777,
525 0.14231483827328514, 0.98982144188093268,
526 0.13052619222005157, 0.99144486137381038,
527 0.12053668025532305, 0.99270887409805397,
528 0.11196447610330786, 0.99371220989324260,
529 0.10452846326765346, 0.99452189536827329,
530 0.09801714032956060, 0.99518472667219693,
533 #define ROTATE( c, s, dc, ds ) \
540 #define WRITE2( j, a, b ) \
543 cfs2[j] = SCALE(b); \
546 double t, scale = 1. / sqrt( (double)n );
549 cfs[0] = SCALE( scale );
551 cfs[1] = SCALE( scale );
558 work_t *cfs2 = cfs + m * n;
562 da0 = a0 = sincos[2 * n - 1];
563 db0 = b0 = sincos[2 * n - 2];
573 for( i = 1; i <= m; i++ )
575 double a = a0 * scale;
576 double b = b0 * scale;
577 double da = a0 * a0 - b0 * b0;
578 double db = a0 * b0 + a0 * b0;
583 for( j = 0; j < m; j += 2 )
586 ROTATE( a, b, da, db );
589 WRITE2( j + 1, a, -b );
590 ROTATE( a, b, da, db );
594 ROTATE( a0, b0, da0, db0 );
603 cvImgToObs_DCT( const void* arr, float *obs, CvSize dctSize,
604 CvSize obsSize, CvSize delta )
606 CV_FUNCNAME( "cvImgToObs_DCT" );
610 CvMat stub, *mat = (CvMat*)arr;
612 CV_CALL( mat = cvGetMat( arr, &stub ));
614 switch( CV_MAT_TYPE( mat->type ))
617 IPPI_CALL( icvImgToObs_DCT_8u32f_C1R( mat->data.ptr, mat->step,
618 cvGetMatSize(mat), obs,
619 dctSize, obsSize, delta ));
622 IPPI_CALL( icvImgToObs_DCT_32f_C1R( mat->data.fl, mat->step,
623 cvGetMatSize(mat), obs,
624 dctSize, obsSize, delta ));
627 CV_ERROR( CV_StsUnsupportedFormat, "" );