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.
47 #include "SubdivMorpher.h"
49 #define MAX_DIFFERENCE 20
51 #define COEFF_MATCH 30
52 #define COEFF_MATCH_2 64
53 #define END_OF_PATH 1000000000
55 #define MAX3(xxx1,xxx2,xxx3) ( ( ( (xxx1) > (xxx2) ) && ( (xxx1) > xxx3 ) ) ? (xxx1) : ( ( (xxx2) > (xxx3) ) ? (xxx2) : (xxx3) ) )
56 #define MAX2(xxx1,xxx2) ( ( (xxx1) > (xxx2) ) ? (xxx1) : (xxx2) )
57 #define MIN3(xxx1,xxx2,xxx3) ( ( ( (xxx1) < (xxx2) ) && ( (xxx1) < xxx3 ) ) ? (xxx1) : ( ( (xxx2) < (xxx3) ) ? (xxx2) : (xxx3) ) )
58 #define MIN2(xxx1,xxx2) ( ( (xxx1) < (xxx2) ) ? (xxx1) : (xxx2) )
60 // This function allocates memory for FindFullCorr function
61 // width - width of image
62 // height - height of image
63 // type - type of memory for allocate ( the size of memory depends on it )
64 // maxPixelDifference - maximum value of pixel difference on two images
65 int* CCvPixelToPixelMorpher::corrAlloc( int width, int height, corrArrayType type, int maxPixelDifference )
72 pointer = ( int* ) malloc( width * height * 2 * sizeof( int ) );
77 pointer = ( int* ) malloc( height * sizeof( int ) );
83 int width_1 = width - 1;
85 pointer = ( int* ) malloc( width * 2 * sizeof( int ) );
86 for( i = 0; i < width; i ++ ) {
87 pointer[ i * 2 ] = i - maxPixelDifference;
88 pointer[ i * 2 + 1 ] = i + maxPixelDifference;
89 } // for( i = 0; i < width; i ++ )
90 for( i = 0; i < width; i ++ ) {
91 if( pointer[ i * 2 ] < 0 ) {
94 if( pointer[ i * 2 + 1 ] >= width ) {
95 pointer[ i * 2 + 1 ] = width_1;
97 } // for( i = 0; i < width; i ++ )
103 pointer = ( int* ) malloc( width * width * 4 * sizeof( int ) );
116 // This function searches correspondences for full image
117 // _leftImage - pointer to 3-channel left image
118 // _leftLineStep - size of one line on the left image in bytes
119 // _rightImage - pointer to 3-channel right image
120 // _rightLineStep - size of one line on the right image in bytes
121 // _corrArray - output integer array of correspondences ( size (width)X(height)X(2) ).
122 // each element of its array consists of two integer values, one of
123 // which represents number of pixel on the left image and the other
124 // corresponding to it point on the right image
125 // _numCorrArray - output array with numbers of finded correspondences on each line
126 // width - width of images
127 // height - height of images
128 // maxPixelDifference - maximum value of pixel difference on two images
129 void CCvPixelToPixelMorpher::FindFullCorr( unsigned char* _leftImage,
131 unsigned char* _rightImage,
137 int maxPixelDifference
140 //int width2 = width * width;
141 //int tempMemorySize = width2 * 4 * sizeof( int );
144 tempMemory = corrAlloc( width, height, CORR_TEMP );
146 int* edges = corrAlloc( width, height, CORR_EDGES, maxPixelDifference );
150 // lines cycle - processes each line
151 for( j = 0; j < height; j ++ )
153 FindCorr( _leftImage + _leftLineStep * j,
154 _rightImage + _rightLineStep * j,
155 _corrArray + width * 2 * j,
161 } // for( j = 0; j < height; j ++ )
168 // This function searches correspondence for one line only
170 void CCvPixelToPixelMorpher::FindCorr( unsigned char* _leftLine,
171 unsigned char* _rightLine,
179 int width2 = width * width;
180 int width_1 = width - 1;
181 int* xArray = tempArray; // array, which shows the best previous point in path
182 int* yArray = tempArray + width2; // array, which shows the best previous point in path
183 int* costArray = tempArray + width2 * 2; // array of costs table
184 int* distArray = tempArray + width2 * 3; // array of distances between points on two images
186 int blockSize = width2 * sizeof( int );
187 memset( ( void* ) xArray, 0, blockSize ); // filling by zero
188 memset( ( void* ) yArray, 0, blockSize ); // filling by zero
189 memset( ( void* ) distArray, 0, blockSize ); // filling by zero
203 // filling cost table by very big value ( initialization )
204 for( j = 0; j < width; j ++ )
206 for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
208 costArray[ j * width + i ] = 2000000000; // filling by very big value
210 } // for( i = edges[ j * 2 ]; i < edges[ j * 2 + 1 ]; i ++ )
212 } // for( j = 0; j < width; j ++ )
214 // computing distances for all pairs of points ( between points on left image and on right image )
215 for( j = 0; j < width; j ++ )
217 for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
219 distArray[ j * width + i ] = distance( _leftLine, _rightLine, width, j, i );
221 } // for( i = edges[ j * 2 ]; i < edges[ j * 2 + 1 ]; i ++ )
223 } // for( j = 0; j < width; j ++ )
225 // filling left upper corner
226 for( i = edges[ 0 ]; i <= edges[ 1 ]; i ++ )
229 xArray[ i ] = END_OF_PATH;
230 costArray[ i ] = *( distArray + i );
232 xArray[ i * width ] = END_OF_PATH;
233 costArray[ i * width ] = *( distArray + i * width );
234 } // for( i = edges[ 0 ]; i <= edges[ 1 ]; i ++ )
236 // normal dynamic programming
237 for( j = 0; j < width_1; j ++ )
239 bestHorCost = costArray[ j * width + edges[ j * 2 ] ];
240 //bestHorCost = 2000000000;
241 for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
243 srcOffset = j * width + i;
244 currCost = costArray[ srcOffset ];
245 if( currCost - COEFF_MATCH < bestHorCost + COEFF_OCC )
247 bestHorCost = currCost;
249 // filling the next horizontal line
254 destOffset = j * width + ( i + width + 1 );
255 futureCost = currCost + distArray[ destOffset ];
256 if( ( xArray[ srcOffset ] == i - 1 ) && ( yArray[ srcOffset ] == j - 1 ) ) {
257 futureCost -= COEFF_MATCH;
259 if( ( xArray[ srcOffset ] != i - 1 ) || ( yArray[ srcOffset ] != j - 1 ) ) {
260 futureCost -= COEFF_MATCH_2;
262 if( costArray[ destOffset ] >= futureCost ) {
263 costArray[ destOffset ] = futureCost;
264 xArray[ destOffset ] = i;
265 yArray[ destOffset ] = j;
268 // residuary points ( if they exist )
269 for( iTemp = i + 2; iTemp <= edges[ j * 2 + 3 ]; iTemp ++ )
271 destOffset = j * width + ( iTemp + width );
272 futureCost = currCost + COEFF_OCC + distArray[ destOffset ];
273 if( costArray[ destOffset ] >= futureCost ) {
274 costArray[ destOffset ] = futureCost;
275 xArray[ destOffset ] = i;
276 yArray[ destOffset ] = j;
279 } // for( iTemp = i + 2; iTemp <= edges[ j * 2 + 3 ]; iTemp ++ )
281 } // if( currCost - COEFF_MATCH < bestHorCost + COEFF_OCC )
283 // filling the next vertical line
286 for( jTemp = j + 2; jTemp <= edges[ i * 2 + 3 ]; jTemp ++ )
288 destOffset = jTemp * width + ( i + 1 );
289 futureCost = currCost + COEFF_OCC + distArray[ destOffset ];
290 if( costArray[ destOffset ] >= futureCost ) {
291 costArray[ destOffset ] = futureCost;
292 xArray[ destOffset ] = i;
293 yArray[ destOffset ] = j;
295 } // for( jTemp = j + 2; jTemp <= edges[ i * 2 + 3 ]; jTemp ++ )
297 } // if( i != width_1 )
299 } // for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
301 } // for( j = 1; j < width; j ++ )
303 // constraction of back path
305 // searching for best initial point in the low right corner
309 int bestCost = costArray[ j * width + i ];
310 for( iTemp = edges[ width * 2 - 2 ]; iTemp < edges[ width * 2 - 1 ]; iTemp ++ )
312 if( costArray[ jTemp * width + iTemp ] < bestCost ) {
315 bestCost = costArray[ jTemp * width + iTemp ];
319 for( jTemp = edges[ width * 2 - 2 ]; jTemp < edges[ width * 2 - 1 ]; jTemp ++ )
321 if( costArray[ jTemp * width + iTemp ] < bestCost ) {
324 bestCost = costArray[ jTemp * width + iTemp ];
329 *( numCorrArray ) = 0;
330 _corrArray[ *( numCorrArray ) ] = j;
331 ( *( numCorrArray ) ) ++;
332 _corrArray[ *( numCorrArray ) ] = i;
333 ( *( numCorrArray ) ) ++;
335 srcOffset = j * width + i;
336 while( xArray[ srcOffset ] != END_OF_PATH )
338 i = xArray[ srcOffset ];
339 j = yArray[ srcOffset ];
340 _corrArray[ *( numCorrArray ) ] = j;
341 ( *( numCorrArray ) ) ++;
342 _corrArray[ *( numCorrArray ) ] = i;
343 ( *( numCorrArray ) ) ++;
344 srcOffset = j * width + i;
345 } // while( xArray[ j * width + i ] != END_OF_PATH )
347 *( numCorrArray ) /= 2;
351 // This function produces morphing of two images into one image, which includes morphed
352 // image or depth map
353 // _leftImage - pointer to left image
354 // _leftLineStep - size of line on left image in bytes
355 // _rightImage - pointer to right image
356 // _rightLineStep - size of line on right image in bytes
357 // _resultImage - pointer to result morphed image
358 // _resultLineStep - size of line on result image in bytes
359 // _corrArray - pointer to array with correspondences
360 // _numCorrArray - pointer to array with numbers correspondeces on each line
361 // width - width of images
362 // height - height of images
363 // alpha - position of virtual camera ( 0 corresponds to left image, 1 - to right one )
364 // imageNeed - defines your wishes. if you want to see normal morphed image you have to set
365 // this parameter to morphNormalImage ( this is default value ), else if you want
366 // to see depth map you have to set this parameter to morphDepthMap and set the
367 // next parameter ( maxPixelDifference ) to real value
368 // maxPixelDifference - maximum value of pixel difference on two images
369 void CCvPixelToPixelMorpher::Morph( unsigned char* _leftImage,
371 unsigned char* _rightImage,
373 unsigned char* _resultImage,
380 morphImageType imageNeed,
384 unsigned char* leftArray = _leftImage;
385 unsigned char* middleArray = _resultImage;
386 unsigned char* rightArray = _rightImage;
387 int leftLineSize = _leftLineStep;
388 int middleLineSize = _resultLineStep;
389 int rightLineSize = _rightLineStep;
392 unsigned char* leftTemp;
393 unsigned char* middleTemp;
394 unsigned char* rightTemp;
409 float alpha1 = 1.0f - alpha;
411 for( lineNumber = 0; lineNumber < height; lineNumber ++ )
413 leftTemp = leftArray + leftLineSize * lineNumber;
414 middleTemp = middleArray + middleLineSize * lineNumber;
415 rightTemp = rightArray + rightLineSize * lineNumber;
416 memset( ( void* )middleTemp, 0, middleLineSize );
418 result = _corrArray + width * 2 * lineNumber;
419 number = _numCorrArray[ lineNumber ];
421 prevLeftPixel = result[ number * 2 - 2 ];
422 prevMiddlePixel = (int)( result[ number * 2 - 2 ] * alpha1 + result[ number * 2 - 1 ] * alpha );
423 prevRightPixel = result[ number * 2 - 1 ];
424 for( i = number - 1; i >= 0; i -- )
426 leftPixel = result[ i * 2 ];
427 rightPixel = result[ i * 2 + 1 ];
428 middlePixel = (int)( leftPixel * alpha1 + rightPixel * alpha );
429 leftPixel3 = leftPixel * 3;
430 middlePixel3 = middlePixel * 3;
431 rightPixel3 = rightPixel * 3;
433 if( imageNeed == morphDepthMap ) {
434 int t = leftPixel - rightPixel + maxDifference;
436 t = t * 255 / maxDifference / 2;
437 middleTemp[ middlePixel3 ] = ( unsigned char )t;
438 middleTemp[ middlePixel3 + 1 ] = ( unsigned char )t;
439 middleTemp[ middlePixel3 + 2 ] = ( unsigned char )t;
440 } // if( imageNeed == morphDepthMap )
443 middleTemp[ middlePixel3 ] =
444 (unsigned char)( leftTemp[ leftPixel3 ] * alpha1 + rightTemp[ rightPixel3 ] * alpha );
445 middleTemp[ middlePixel3 + 1 ] =
446 (unsigned char)( leftTemp[ leftPixel3 + 1 ] * alpha1 + rightTemp[ rightPixel3 + 1 ] * alpha );
447 middleTemp[ middlePixel3 + 2 ] =
448 (unsigned char)( leftTemp[ leftPixel3 + 2 ] * alpha1 + rightTemp[ rightPixel3 + 2 ] * alpha );
450 if( middlePixel - prevMiddlePixel > 1 ) // occlusion
452 if( leftPixel - prevLeftPixel > 1 )
454 int LenSrc = leftPixel - prevLeftPixel - 2;
455 int LenDest = middlePixel - prevMiddlePixel - 1;
456 for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
458 tempIndex = prevLeftPixel + 1 + LenSrc * ( j - prevMiddlePixel - 1 ) / LenDest;
459 middleTemp[ j * 3 ] = leftTemp[ tempIndex * 3 ];
460 middleTemp[ j * 3 + 1 ] = leftTemp[ tempIndex * 3 + 1 ];
461 middleTemp[ j * 3 + 2 ] = leftTemp[ tempIndex * 3 + 2 ];
463 } // if( leftPixel - prevLeftPixel > 1 )
466 int LenSrc = rightPixel - prevRightPixel - 2;
467 int LenDest = middlePixel - prevMiddlePixel - 1;
468 for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
470 tempIndex = prevRightPixel + 1 + LenSrc * ( j - prevMiddlePixel - 1 ) / LenDest;
471 middleTemp[ j * 3 ] = rightTemp[ tempIndex * 3 ];
472 middleTemp[ j * 3 + 1 ] = rightTemp[ tempIndex * 3 + 1 ];
473 middleTemp[ j * 3 + 2 ] = rightTemp[ tempIndex * 3 + 2 ];
475 } // if( leftPixel - prevLeftPixel > 1 ) else
477 } // if( middlePixel - prevMiddlePixel > 1 )
479 } // if( imageNeed == morphDepthMap ) else
480 prevLeftPixel = leftPixel;
481 prevRightPixel = rightPixel;
482 prevMiddlePixel = middlePixel;
483 } // for( i = number - 1; i >= 0; i -- )
485 } // for( lineNumber = 0; lineNumber < LeftImage -> m_Raster -> GetHeight() )
489 // This function calculates color difference between two points ( one on the left image and one on the other )
490 // _leftLine - pointer to line on the left image
491 // _rightLine - pointer to line on the right image
492 // lineSize - width of line in points
493 // x - index of interesting point on the left image
494 // y - index of interesting point on the right image
495 int CCvPixelToPixelMorpher::distance( unsigned char* _leftLine,
496 unsigned char* _rightLine,
538 assert( lineSize > 0 );
540 _Color* leftPixel = ( _Color* )( _leftLine ) + x;
541 _Color* rightPixel = ( _Color* )( _rightLine ) + y;
543 if( lineSize == 1 ) {
544 DRed = leftPixel->red - rightPixel->red;
545 DRed = MAX2( DRed, -DRed );
546 DGreen = leftPixel->green - rightPixel->green;
547 DGreen = MAX2( DGreen, -DGreen );
548 DBlue = leftPixel->blue - rightPixel->blue;
549 DBlue = MAX2( DBlue, -DBlue );
550 return MAX3( DRed, DGreen, DBlue );
556 else if( x == lineSize - 1 )
564 else if( y == lineSize - 1 )
569 state = yState * 3 + xState;
573 case 0: // xState = yState = 0
576 temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
577 temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
578 IlMaxRed = MAX3( leftPixel->red, temp1, temp2 );
579 IlMinRed = MIN3( leftPixel->red, temp1, temp2 );
580 temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
581 temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
582 IrMaxRed = MAX3( rightPixel->red, temp1, temp2 );
583 IrMinRed = MIN3( rightPixel->red, temp1, temp2 );
585 temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
586 temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
587 IlMaxGreen = MAX3( leftPixel->green, temp1, temp2 );
588 IlMinGreen = MIN3( leftPixel->green, temp1, temp2 );
589 temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
590 temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
591 IrMaxGreen = MAX3( rightPixel->green, temp1, temp2 );
592 IrMinGreen = MIN3( rightPixel->green, temp1, temp2 );
594 temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
595 temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
596 IlMaxBlue = MAX3( leftPixel->blue, temp1, temp2 );
597 IlMinBlue = MIN3( leftPixel->blue, temp1, temp2 );
598 temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
599 temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
600 IrMaxBlue = MAX3( rightPixel->blue, temp1, temp2 );
601 IrMinBlue = MIN3( rightPixel->blue, temp1, temp2 );
604 temp1 = leftPixel->red - IrMaxRed;
605 temp2 = IrMinRed - leftPixel->red;
606 DlRed = MAX3( 0, temp1, temp2 );
607 temp1 = rightPixel->red - IlMaxRed;
608 temp2 = IlMinRed - rightPixel->red;
609 DrRed = MAX3( 0, temp1, temp2 );
611 temp1 = leftPixel->green - IrMaxGreen;
612 temp2 = IrMinGreen - leftPixel->green;
613 DlGreen = MAX3( 0, temp1, temp2 );
614 temp1 = rightPixel->green - IlMaxGreen;
615 temp2 = IlMinGreen - rightPixel->green;
616 DrGreen = MAX3( 0, temp1, temp2 );
618 temp1 = leftPixel->blue - IrMaxBlue;
619 temp2 = IrMinBlue - leftPixel->blue;
620 DlBlue = MAX3( 0, temp1, temp2 );
621 temp1 = rightPixel->blue - IlMaxBlue;
622 temp2 = IlMinBlue - rightPixel->blue;
623 DrBlue = MAX3( 0, temp1, temp2 );
627 case -1: // xState = -1, yState = 0
630 temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
631 IlMaxRed = MAX2( leftPixel->red, temp2 );
632 IlMinRed = MIN2( leftPixel->red, temp2 );
633 temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
634 temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
635 IrMaxRed = MAX3( rightPixel->red, temp1, temp2 );
636 IrMinRed = MIN3( rightPixel->red, temp1, temp2 );
638 temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
639 IlMaxGreen = MAX2( leftPixel->green, temp2 );
640 IlMinGreen = MIN2( leftPixel->green, temp2 );
641 temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
642 temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
643 IrMaxGreen = MAX3( rightPixel->green, temp1, temp2 );
644 IrMinGreen = MIN3( rightPixel->green, temp1, temp2 );
646 temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
647 IlMaxBlue = MAX2( leftPixel->blue, temp2 );
648 IlMinBlue = MIN2( leftPixel->blue, temp2 );
649 temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
650 temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
651 IrMaxBlue = MAX3( rightPixel->blue, temp1, temp2 );
652 IrMinBlue = MIN3( rightPixel->blue, temp1, temp2 );
655 temp1 = leftPixel->red - IrMaxRed;
656 temp2 = IrMinRed - leftPixel->red;
657 DlRed = MAX3( 0, temp1, temp2 );
658 temp1 = rightPixel->red - IlMaxRed;
659 temp2 = IlMinRed - rightPixel->red;
660 DrRed = MAX3( 0, temp1, temp2 );
662 temp1 = leftPixel->green - IrMaxGreen;
663 temp2 = IrMinGreen - leftPixel->green;
664 DlGreen = MAX3( 0, temp1, temp2 );
665 temp1 = rightPixel->green - IlMaxGreen;
666 temp2 = IlMinGreen - rightPixel->green;
667 DrGreen = MAX3( 0, temp1, temp2 );
669 temp1 = leftPixel->blue - IrMaxBlue;
670 temp2 = IrMinBlue - leftPixel->blue;
671 DlBlue = MAX3( 0, temp1, temp2 );
672 temp1 = rightPixel->blue - IlMaxBlue;
673 temp2 = IlMinBlue - rightPixel->blue;
674 DrBlue = MAX3( 0, temp1, temp2 );
678 case 1: // xState = 1, yState = 0
681 temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
682 IlMaxRed = MAX2( leftPixel->red, temp1 );
683 IlMinRed = MIN2( leftPixel->red, temp1 );
684 temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
685 temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
686 IrMaxRed = MAX3( rightPixel->red, temp1, temp2 );
687 IrMinRed = MIN3( rightPixel->red, temp1, temp2 );
689 temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
690 IlMaxGreen = MAX2( leftPixel->green, temp1 );
691 IlMinGreen = MIN2( leftPixel->green, temp1 );
692 temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
693 temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
694 IrMaxGreen = MAX3( rightPixel->green, temp1, temp2 );
695 IrMinGreen = MIN3( rightPixel->green, temp1, temp2 );
697 temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
698 IlMaxBlue = MAX2( leftPixel->blue, temp1 );
699 IlMinBlue = MIN2( leftPixel->blue, temp1 );
700 temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
701 temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
702 IrMaxBlue = MAX3( rightPixel->blue, temp1, temp2 );
703 IrMinBlue = MIN3( rightPixel->blue, temp1, temp2 );
706 temp1 = leftPixel->red - IrMaxRed;
707 temp2 = IrMinRed - leftPixel->red;
708 DlRed = MAX3( 0, temp1, temp2 );
709 temp1 = rightPixel->red - IlMaxRed;
710 temp2 = IlMinRed - rightPixel->red;
711 DrRed = MAX3( 0, temp1, temp2 );
713 temp1 = leftPixel->green - IrMaxGreen;
714 temp2 = IrMinGreen - leftPixel->green;
715 DlGreen = MAX3( 0, temp1, temp2 );
716 temp1 = rightPixel->green - IlMaxGreen;
717 temp2 = IlMinGreen - rightPixel->green;
718 DrGreen = MAX3( 0, temp1, temp2 );
720 temp1 = leftPixel->blue - IrMaxBlue;
721 temp2 = IrMinBlue - leftPixel->blue;
722 DlBlue = MAX3( 0, temp1, temp2 );
723 temp1 = rightPixel->blue - IlMaxBlue;
724 temp2 = IlMinBlue - rightPixel->blue;
725 DrBlue = MAX3( 0, temp1, temp2 );
729 case -3: // xState = 0, yState = -1
732 temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
733 temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
734 IlMaxRed = MAX3( leftPixel->red, temp1, temp2 );
735 IlMinRed = MIN3( leftPixel->red, temp1, temp2 );
736 temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
737 IrMaxRed = MAX2( rightPixel->red, temp2 );
738 IrMinRed = MIN2( rightPixel->red, temp2 );
740 temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
741 temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
742 IlMaxGreen = MAX3( leftPixel->green, temp1, temp2 );
743 IlMinGreen = MIN3( leftPixel->green, temp1, temp2 );
744 temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
745 IrMaxGreen = MAX2( rightPixel->green, temp2 );
746 IrMinGreen = MIN2( rightPixel->green, temp2 );
748 temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
749 temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
750 IlMaxBlue = MAX3( leftPixel->blue, temp1, temp2 );
751 IlMinBlue = MIN3( leftPixel->blue, temp1, temp2 );
752 temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
753 IrMaxBlue = MAX2( rightPixel->blue, temp2 );
754 IrMinBlue = MIN2( rightPixel->blue, temp2 );
757 temp1 = leftPixel->red - IrMaxRed;
758 temp2 = IrMinRed - leftPixel->red;
759 DlRed = MAX3( 0, temp1, temp2 );
760 temp1 = rightPixel->red - IlMaxRed;
761 temp2 = IlMinRed - rightPixel->red;
762 DrRed = MAX3( 0, temp1, temp2 );
764 temp1 = leftPixel->green - IrMaxGreen;
765 temp2 = IrMinGreen - leftPixel->green;
766 DlGreen = MAX3( 0, temp1, temp2 );
767 temp1 = rightPixel->green - IlMaxGreen;
768 temp2 = IlMinGreen - rightPixel->green;
769 DrGreen = MAX3( 0, temp1, temp2 );
771 temp1 = leftPixel->blue - IrMaxBlue;
772 temp2 = IrMinBlue - leftPixel->blue;
773 DlBlue = MAX3( 0, temp1, temp2 );
774 temp1 = rightPixel->blue - IlMaxBlue;
775 temp2 = IlMinBlue - rightPixel->blue;
776 DrBlue = MAX3( 0, temp1, temp2 );
780 case 3: // xState = 0, yState = 1
783 temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
784 temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
785 IlMaxRed = MAX3( leftPixel->red, temp1, temp2 );
786 IlMinRed = MIN3( leftPixel->red, temp1, temp2 );
787 temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
788 IrMaxRed = MAX2( rightPixel->red, temp1 );
789 IrMinRed = MIN2( rightPixel->red, temp1 );
791 temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
792 temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
793 IlMaxGreen = MAX3( leftPixel->green, temp1, temp2 );
794 IlMinGreen = MIN3( leftPixel->green, temp1, temp2 );
795 temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
796 IrMaxGreen = MAX2( rightPixel->green, temp1 );
797 IrMinGreen = MIN2( rightPixel->green, temp1 );
799 temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
800 temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
801 IlMaxBlue = MAX3( leftPixel->blue, temp1, temp2 );
802 IlMinBlue = MIN3( leftPixel->blue, temp1, temp2 );
803 temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
804 IrMaxBlue = MAX2( rightPixel->blue, temp1 );
805 IrMinBlue = MIN2( rightPixel->blue, temp1 );
808 temp1 = leftPixel->red - IrMaxRed;
809 temp2 = IrMinRed - leftPixel->red;
810 DlRed = MAX3( 0, temp1, temp2 );
811 temp1 = rightPixel->red - IlMaxRed;
812 temp2 = IlMinRed - rightPixel->red;
813 DrRed = MAX3( 0, temp1, temp2 );
815 temp1 = leftPixel->green - IrMaxGreen;
816 temp2 = IrMinGreen - leftPixel->green;
817 DlGreen = MAX3( 0, temp1, temp2 );
818 temp1 = rightPixel->green - IlMaxGreen;
819 temp2 = IlMinGreen - rightPixel->green;
820 DrGreen = MAX3( 0, temp1, temp2 );
822 temp1 = leftPixel->blue - IrMaxBlue;
823 temp2 = IrMinBlue - leftPixel->blue;
824 DlBlue = MAX3( 0, temp1, temp2 );
825 temp1 = rightPixel->blue - IlMaxBlue;
826 temp2 = IlMinBlue - rightPixel->blue;
827 DrBlue = MAX3( 0, temp1, temp2 );
831 case -2: // xState = 1, yState = -1
834 temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
835 IlMaxRed = MAX2( leftPixel->red, temp1 );
836 IlMinRed = MIN2( leftPixel->red, temp1 );
837 temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
838 IrMaxRed = MAX2( rightPixel->red, temp2 );
839 IrMinRed = MIN2( rightPixel->red, temp2 );
841 temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
842 IlMaxGreen = MAX2( leftPixel->green, temp1 );
843 IlMinGreen = MIN2( leftPixel->green, temp1 );
844 temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
845 IrMaxGreen = MAX2( rightPixel->green, temp2 );
846 IrMinGreen = MIN2( rightPixel->green, temp2 );
848 temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
849 IlMaxBlue = MAX2( leftPixel->blue, temp1 );
850 IlMinBlue = MIN2( leftPixel->blue, temp1 );
851 temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
852 IrMaxBlue = MAX2( rightPixel->blue, temp2 );
853 IrMinBlue = MIN2( rightPixel->blue, temp2 );
856 temp1 = leftPixel->red - IrMaxRed;
857 temp2 = IrMinRed - leftPixel->red;
858 DlRed = MAX3( 0, temp1, temp2 );
859 temp1 = rightPixel->red - IlMaxRed;
860 temp2 = IlMinRed - rightPixel->red;
861 DrRed = MAX3( 0, temp1, temp2 );
863 temp1 = leftPixel->green - IrMaxGreen;
864 temp2 = IrMinGreen - leftPixel->green;
865 DlGreen = MAX3( 0, temp1, temp2 );
866 temp1 = rightPixel->green - IlMaxGreen;
867 temp2 = IlMinGreen - rightPixel->green;
868 DrGreen = MAX3( 0, temp1, temp2 );
870 temp1 = leftPixel->blue - IrMaxBlue;
871 temp2 = IrMinBlue - leftPixel->blue;
872 DlBlue = MAX3( 0, temp1, temp2 );
873 temp1 = rightPixel->blue - IlMaxBlue;
874 temp2 = IlMinBlue - rightPixel->blue;
875 DrBlue = MAX3( 0, temp1, temp2 );
879 case 2: // xState = -1, yState = 1
882 temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
883 IlMaxRed = MAX2( leftPixel->red, temp2 );
884 IlMinRed = MIN2( leftPixel->red, temp2 );
885 temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
886 IrMaxRed = MAX2( rightPixel->red, temp1 );
887 IrMinRed = MIN2( rightPixel->red, temp1 );
889 temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
890 IlMaxGreen = MAX2( leftPixel->green, temp2 );
891 IlMinGreen = MIN2( leftPixel->green, temp2 );
892 temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
893 IrMaxGreen = MAX2( rightPixel->green, temp1 );
894 IrMinGreen = MIN2( rightPixel->green, temp1 );
896 temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
897 IlMaxBlue = MAX2( leftPixel->blue, temp2 );
898 IlMinBlue = MIN2( leftPixel->blue, temp2 );
899 temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
900 IrMaxBlue = MAX2( rightPixel->blue, temp1 );
901 IrMinBlue = MIN2( rightPixel->blue, temp1 );
904 temp1 = leftPixel->red - IrMaxRed;
905 temp2 = IrMinRed - leftPixel->red;
906 DlRed = MAX3( 0, temp1, temp2 );
907 temp1 = rightPixel->red - IlMaxRed;
908 temp2 = IlMinRed - rightPixel->red;
909 DrRed = MAX3( 0, temp1, temp2 );
911 temp1 = leftPixel->green - IrMaxGreen;
912 temp2 = IrMinGreen - leftPixel->green;
913 DlGreen = MAX3( 0, temp1, temp2 );
914 temp1 = rightPixel->green - IlMaxGreen;
915 temp2 = IlMinGreen - rightPixel->green;
916 DrGreen = MAX3( 0, temp1, temp2 );
918 temp1 = leftPixel->blue - IrMaxBlue;
919 temp2 = IrMinBlue - leftPixel->blue;
920 DlBlue = MAX3( 0, temp1, temp2 );
921 temp1 = rightPixel->blue - IlMaxBlue;
922 temp2 = IlMinBlue - rightPixel->blue;
923 DrBlue = MAX3( 0, temp1, temp2 );
927 case -4: // xState = -1, yState = -1
930 temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
931 IlMaxRed = MAX2( leftPixel->red, temp2 );
932 IlMinRed = MIN2( leftPixel->red, temp2 );
933 temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
934 IrMaxRed = MAX2( rightPixel->red, temp2 );
935 IrMinRed = MIN2( rightPixel->red, temp2 );
937 temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
938 IlMaxGreen = MAX2( leftPixel->green, temp2 );
939 IlMinGreen = MIN2( leftPixel->green, temp2 );
940 temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
941 IrMaxGreen = MAX2( rightPixel->green, temp2 );
942 IrMinGreen = MIN2( rightPixel->green, temp2 );
944 temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
945 IlMaxBlue = MAX2( leftPixel->blue, temp2 );
946 IlMinBlue = MIN2( leftPixel->blue, temp2 );
947 temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
948 IrMaxBlue = MAX2( rightPixel->blue, temp2 );
949 IrMinBlue = MIN2( rightPixel->blue, temp2 );
952 temp1 = leftPixel->red - IrMaxRed;
953 temp2 = IrMinRed - leftPixel->red;
954 DlRed = MAX3( 0, temp1, temp2 );
955 temp1 = rightPixel->red - IlMaxRed;
956 temp2 = IlMinRed - rightPixel->red;
957 DrRed = MAX3( 0, temp1, temp2 );
959 temp1 = leftPixel->green - IrMaxGreen;
960 temp2 = IrMinGreen - leftPixel->green;
961 DlGreen = MAX3( 0, temp1, temp2 );
962 temp1 = rightPixel->green - IlMaxGreen;
963 temp2 = IlMinGreen - rightPixel->green;
964 DrGreen = MAX3( 0, temp1, temp2 );
966 temp1 = leftPixel->blue - IrMaxBlue;
967 temp2 = IrMinBlue - leftPixel->blue;
968 DlBlue = MAX3( 0, temp1, temp2 );
969 temp1 = rightPixel->blue - IlMaxBlue;
970 temp2 = IlMinBlue - rightPixel->blue;
971 DrBlue = MAX3( 0, temp1, temp2 );
975 case 4: // xState = 1, yState = 1
979 temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
980 IlMaxRed = MAX2( leftPixel->red, temp1 );
981 IlMinRed = MIN2( leftPixel->red, temp1 );
982 temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
983 IrMaxRed = MAX2( rightPixel->red, temp1 );
984 IrMinRed = MIN2( rightPixel->red, temp1 );
986 temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
987 IlMaxGreen = MAX2( leftPixel->green, temp1 );
988 IlMinGreen = MIN2( leftPixel->green, temp1 );
989 temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
990 IrMaxGreen = MAX2( rightPixel->green, temp1 );
991 IrMinGreen = MIN2( rightPixel->green, temp1 );
993 temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
994 IlMaxBlue = MAX2( leftPixel->blue, temp1 );
995 IlMinBlue = MIN2( leftPixel->blue, temp1 );
996 temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
997 IrMaxBlue = MAX2( rightPixel->blue, temp1 );
998 IrMinBlue = MIN2( rightPixel->blue, temp1 );
1001 temp1 = leftPixel->red - IrMaxRed;
1002 temp2 = IrMinRed - leftPixel->red;
1003 DlRed = MAX3( 0, temp1, temp2 );
1004 temp1 = rightPixel->red - IlMaxRed;
1005 temp2 = IlMinRed - rightPixel->red;
1006 DrRed = MAX3( 0, temp1, temp2 );
1008 temp1 = leftPixel->green - IrMaxGreen;
1009 temp2 = IrMinGreen - leftPixel->green;
1010 DlGreen = MAX3( 0, temp1, temp2 );
1011 temp1 = rightPixel->green - IlMaxGreen;
1012 temp2 = IlMinGreen - rightPixel->green;
1013 DrGreen = MAX3( 0, temp1, temp2 );
1015 temp1 = leftPixel->blue - IrMaxBlue;
1016 temp2 = IrMinBlue - leftPixel->blue;
1017 DlBlue = MAX3( 0, temp1, temp2 );
1018 temp1 = rightPixel->blue - IlMaxBlue;
1019 temp2 = IlMinBlue - rightPixel->blue;
1020 DrBlue = MAX3( 0, temp1, temp2 );
1023 } // switch( state )
1025 DRed = MIN2( DlRed, DrRed );
1026 DGreen = MIN2( DlGreen, DrGreen );
1027 DBlue = MIN2( DlBlue, DrBlue );
1028 //DRed = MAX2( DlRed, DrRed );
1029 //DGreen = MAX2( DlGreen, DrGreen );
1030 //DBlue = MAX2( DlBlue, DrBlue );
1032 dist = MAX3( DRed, DGreen, DBlue );
1033 //dist = ( DRed + DGreen + DBlue ) / 3;
1034 //dist = ( DRed + DGreen + DBlue ) + MAX3( DRed, DGreen, DBlue );
1040 bool CCvPixelToPixelMorpher::OnCalculateStereo()
1042 CvSize imageSizeLeft = GetImageSize( m_left_img ),
1043 imageSizeRight = GetImageSize( m_right_img );
1045 if( ( imageSizeLeft.width != imageSizeRight.width )
1046 || ( imageSizeLeft.height != imageSizeRight.height ) )
1055 m_corr = corrAlloc( m_left_img -> width,
1056 m_left_img -> height,
1062 m_corrNum = corrAlloc( m_left_img -> width,
1063 m_right_img -> height,
1066 // Find correspondence for full image and store it to corr array
1067 FindFullCorr( ( unsigned char* )m_left_img -> imageData,
1068 m_left_img -> widthStep,
1069 ( unsigned char* )m_right_img -> imageData,
1070 m_right_img -> widthStep,
1073 m_left_img -> width,
1074 m_left_img -> height,
1075 m_maxPixelDifference
1078 m_isStereoReady = true;
1083 bool CCvPixelToPixelMorpher::OnCalculateVirtualImage()
1085 // Output image to ResultImage window
1086 Morph( ( unsigned char* )m_left_img -> imageData,
1087 m_left_img ->widthStep,
1088 ( unsigned char* )m_right_img -> imageData,
1089 m_right_img -> widthStep,
1090 ( unsigned char* )m_virtual_img -> imageData,
1091 m_virtual_img -> widthStep,
1094 m_left_img -> width,
1095 m_left_img -> height,
1098 m_isVirtualImageReady = true;
1103 bool CCvPixelToPixelMorpher::OnCalculateDisparity()
1105 Morph( ( unsigned char* )m_left_img -> imageData,
1106 m_left_img ->widthStep,
1107 ( unsigned char* )m_right_img -> imageData,
1108 m_right_img -> widthStep,
1109 ( unsigned char* )m_disparity_img -> imageData,
1110 m_disparity_img -> widthStep,
1113 m_left_img -> width,
1114 m_left_img -> height,
1117 m_maxPixelDifference );
1122 bool CCvPixelToPixelMorpher::OnCalculateDisparityImage()
1124 Morph( ( unsigned char* )m_left_img -> imageData,
1125 m_left_img ->widthStep,
1126 ( unsigned char* )m_right_img -> imageData,
1127 m_right_img -> widthStep,
1128 ( unsigned char* )m_disparity_img -> imageData,
1129 m_disparity_img -> widthStep,
1132 m_left_img -> width,
1133 m_left_img -> height,
1136 m_maxPixelDifference );
1141 CCvPixelToPixelMorpher::CCvPixelToPixelMorpher()
1143 m_maxPixelDifference = MAX_DIFFERENCE;
1144 m_corr = m_corrNum = 0;
1145 m_isStereoReady = false;
1146 m_isVirtualImageReady = false;
1147 m_isDisparityReady = false;
1148 //m_isDisparityImageReady = false;