| /* @(#) Functions which improve the selection of two ttie points pairs in two |
| * @(#) images, by estimating the correlation coefficient given in page 426 |
| * @(#) 2nd edn of the book Digital Image processing Gonzalez and Wintz |
| * @(#) The function works as follows: |
| * @(#) It expects to receive nopoints pairs (coordinates) of points |
| * @(#) corresponding to ref and sec. |
| * @(#) The coordinates of the pairs are in arrays x1,y1 and x2,y2 |
| * @(#) After that the program reads a region of 2*halfcorsize +1 pels centered |
| * @(#) at point (x1, y1) and looks around |
| * @(#) an area 2*halfareasize+1 centered at point (x2, y2). |
| * @(#) For each point in this 2*halfareasize+1, |
| * @(#) the program reads the corresponding |
| * @(#) image2 values in a region of 2*halfcorsize+1 pels centered at this point |
| * @(#) and calculates the corresponding correlation coefficients. |
| * @(#) The result is stored in a the array |
| * @(#) corcoef[(2*halfareasize+1)(2*halfareasize+1)]. Within this window, the |
| * @(#) max correlation coefficient is estimated and its corresponding |
| * @(#) (x, y) coordinates are returned in (x2, y2). |
| * @(#) The purpose of this function is to improve the selection of |
| * @(#) control points entered in (x1, y1) |
| * @(#) Both input images should are either memory mapped or in a buffer. |
| * @(#) The variable bandno should be between 1 and ref->Bands |
| * @(#) The program fills the dx[] and dy[] arrays before returning. |
| * @(#) |
| * @(#) int im__chkpair( ref, sec, bandno, points ) |
| * @(#) IMAGE *ref, *sec; |
| * @(#) int bandno; |
| * @(#) TIE_POINTS *points; |
| * @(#) |
| * @(#) Returns 0 on sucess and -1 on error. |
| * |
| * Copyright: 1990, N. Dessipris. |
| * |
| * Author: Nicos Dessipris |
| * Written on: 02/05/1990 |
| * Modified on : 18/04/1991 |
| * 8/7/93 JC |
| * - allows IM_CODING_LABQ coding |
| * - now calls im_incheck() |
| * 13/7/95 JC |
| * - rewritten |
| * - now uses im_spcor() |
| * 13/8/96 JC |
| * - order of args changed to help C++ API |
| */ |
| |
| /* |
| |
| This file is part of VIPS. |
| |
| VIPS is free software; you can redistribute it and/or modify |
| it under the terms of the GNU Lesser General Public License as published by |
| the Free Software Foundation; either version 2 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
| */ |
| |
| /* |
| |
| These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk |
| |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif /*HAVE_CONFIG_H*/ |
| #include <vips/intl.h> |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <math.h> |
| |
| #include <vips/vips.h> |
| |
| #include "mosaic.h" |
| |
| #ifdef WITH_DMALLOC |
| #include <dmalloc.h> |
| #endif /*WITH_DMALLOC*/ |
| |
| /* Find position of sec within ref. Search around point xsec, ysec for the |
| * best match for the area around xref, yref. Search an area of size |
| * hsearchsize for an of size hwindowsize. |
| * |
| * Return a new value for xsec, ysec and the correlation at that point. |
| * |
| * Also used by im_match_linear(), im_match_linear_search(), etc. |
| */ |
| int |
| im_correl( IMAGE *ref, IMAGE *sec, |
| int xref, int yref, int xsec, int ysec, |
| int hwindowsize, int hsearchsize, |
| double *correlation, int *x, int *y ) |
| { |
| IMAGE *surface = im_open( "surface", "t" ); |
| IMAGE *t1, *t2, *t3, *t4; |
| |
| Rect refr, secr; |
| Rect winr, srhr; |
| Rect wincr, srhcr; |
| |
| if( !surface || |
| !(t1 = im_open_local( surface, "correlate:1", "p" )) || |
| !(t2 = im_open_local( surface, "correlate:1", "p" )) || |
| !(t3 = im_open_local( surface, "correlate:1", "p" )) || |
| !(t4 = im_open_local( surface, "correlate:1", "p" )) ) |
| return( -1 ); |
| |
| /* Find position of window and search area, and clip against image |
| * size. |
| */ |
| refr.left = 0; |
| refr.top = 0; |
| refr.width = ref->Xsize; |
| refr.height = ref->Ysize; |
| winr.left = xref - hwindowsize; |
| winr.top = yref - hwindowsize; |
| winr.width = hwindowsize*2 + 1; |
| winr.height = hwindowsize*2 + 1; |
| im_rect_intersectrect( &refr, &winr, &wincr ); |
| |
| secr.left = 0; |
| secr.top = 0; |
| secr.width = sec->Xsize; |
| secr.height = sec->Ysize; |
| srhr.left = xsec - hsearchsize; |
| srhr.top = ysec - hsearchsize; |
| srhr.width = hsearchsize*2 + 1; |
| srhr.height = hsearchsize*2 + 1; |
| im_rect_intersectrect( &secr, &srhr, &srhcr ); |
| |
| /* Extract window and search area. |
| */ |
| if( im_extract_area( ref, t1, |
| wincr.left, wincr.top, wincr.width, wincr.height ) || |
| im_extract_area( sec, t2, |
| srhcr.left, srhcr.top, srhcr.width, srhcr.height ) ) { |
| im_close( surface ); |
| return( -1 ); |
| } |
| |
| /* Make sure we have just one band. From im_*mosaic() we will, but |
| * from im_match_linear_search() etc. we may not. |
| */ |
| if( t1->Bands != 1 ) { |
| if( im_extract_band( t1, t3, 0 ) ) { |
| im_close( surface ); |
| return( -1 ); |
| } |
| t1 = t3; |
| } |
| if( t2->Bands != 1 ) { |
| if( im_extract_band( t2, t4, 0 ) ) { |
| im_close( surface ); |
| return( -1 ); |
| } |
| t2 = t4; |
| } |
| |
| /* Search! |
| */ |
| if( im_spcor( t2, t1, surface ) ) { |
| im_close( surface ); |
| return( -1 ); |
| } |
| |
| /* Find maximum of correlation surface. |
| */ |
| if( im_maxpos( surface, x, y, correlation ) ) { |
| im_close( surface ); |
| return( -1 ); |
| } |
| im_close( surface ); |
| |
| /* Translate back to position within sec. |
| */ |
| *x += srhcr.left; |
| *y += srhcr.top; |
| |
| return( 0 ); |
| } |
| |
| int |
| im__chkpair( IMAGE *ref, IMAGE *sec, TIE_POINTS *points ) |
| { |
| int i; |
| int x, y; |
| double correlation; |
| |
| const int hcor = points->halfcorsize; |
| const int harea = points->halfareasize; |
| |
| /* Check images. |
| */ |
| if( im_incheck( ref ) || im_incheck( sec ) ) |
| return( -1 ); |
| if( ref->Bands != sec->Bands || ref->BandFmt != sec->BandFmt || |
| ref->Coding != sec->Coding ) { |
| im_error( "im_chkpair", "%s", _( "inputs incompatible" ) ); |
| return( -1 ); |
| } |
| if( ref->Bands != 1 || ref->BandFmt != IM_BANDFMT_UCHAR ) { |
| im_error( "im_chkpair", "%s", _( "help!" ) ); |
| return( -1 ); |
| } |
| |
| for( i = 0; i < points->nopoints; i++ ) { |
| /* Find correlation point. |
| */ |
| if( im_correl( ref, sec, |
| points->x_reference[i], points->y_reference[i], |
| points->x_reference[i], points->y_reference[i], |
| hcor, harea, |
| &correlation, &x, &y ) ) |
| return( -1 ); |
| |
| /* And note in x_secondary. |
| */ |
| points->x_secondary[i] = x; |
| points->y_secondary[i] = y; |
| points->correlation[i] = correlation; |
| |
| /* Note each dx, dy too. |
| */ |
| points->dx[i] = |
| points->x_secondary[i] - points->x_reference[i]; |
| points->dy[i] = |
| points->y_secondary[i] - points->y_reference[i]; |
| } |
| |
| return( 0 ); |
| } |