001 #include <opencv2/opencv.hpp> 002 #include <opencv2/opencv_lib.hpp> 003 004 void cvShiftDFT(CvArr *src_arr, CvArr *dst_arr); 005 006 void myDftImage(IplImage *imageSrc, CvMat *matComp) { 007 CvMat *matReal, *matImag; 008 CvSize size; 009 int sizeX, sizeY; 010 int sx, sy; 011 double r, g, b; 012 013 size = cvGetSize(imageSrc); 014 sizeX = size.width; sizeY = size.height; 015 016 matReal = cvCreateMat(sizeY, sizeX, CV_64FC1); 017 matImag = cvCreateMat(sizeY, sizeX, CV_64FC1); 018 019 for(sy = 0; sy < sizeY; sy++) { 020 for(sx = 0; sx < sizeX; sx++) { 021 b = ((uchar*)(imageSrc->imageData + imageSrc->widthStep * sy))[imageSrc->nChannels * sx + 0]; 022 g = ((uchar*)(imageSrc->imageData + imageSrc->widthStep * sy))[imageSrc->nChannels * sx + 1]; 023 r = ((uchar*)(imageSrc->imageData + imageSrc->widthStep * sy))[imageSrc->nChannels * sx + 2]; 024 (matReal->data.db + matReal->height * sy)[sx] = (0.299 * r + 0.587 * g + 0.114 * b) / 255.0; 025 } 026 } 027 028 cvSetZero(matImag); 029 cvMerge(matReal, matImag, NULL, NULL, matComp); 030 031 cvDFT(matComp, matComp, CV_DXT_FORWARD); 032 033 cvReleaseMat(&matReal); 034 cvReleaseMat(&matImag); 035 036 return; 037 } 038 039 void myNormalizeMat(CvMat *matCompSrc, CvMat *matCompDst) { 040 CvMat *matReal, *matImag; 041 CvMat *matAmp; 042 043 matReal = cvCreateMat(matCompSrc->height, matCompSrc->width, CV_64FC1); 044 matImag = cvCreateMat(matCompSrc->height, matCompSrc->width, CV_64FC1); 045 matAmp = cvCreateMat(matCompSrc->height, matCompSrc->width, CV_64FC1); 046 047 cvSplit(matCompSrc, matReal, matImag, NULL, NULL); 048 049 cvPow(matReal, matReal, 2.0); cvPow(matImag, matImag, 2.0); 050 cvAdd(matReal, matImag, matAmp, NULL); 051 cvPow(matAmp, matAmp, 0.5); 052 053 cvSplit(matCompSrc, matReal, matImag, NULL, NULL); 054 055 cvDiv(matReal, matAmp, matReal, 1.0); 056 cvDiv(matImag, matAmp, matImag, 1.0); 057 058 cvMerge(matReal, matImag, NULL, NULL, matCompDst); 059 060 cvReleaseMat(&matReal); 061 cvReleaseMat(&matImag); 062 cvReleaseMat(&matAmp); 063 064 return; 065 } 066 067 int main(int argc, char *argv[]) { 068 IplImage *imageOrg0, *imageOrg1; 069 IplImage *imagePha; 070 CvMat *matComp0, *matComp1; 071 CvMat *matReal, *matImag; 072 CvSize size; 073 int sizeX, sizeY; 074 075 if(argc != 3) { 076 printf("Usage: %s <ImageFile0> <ImageFile1>\n", argv[0]); 077 exit(-1); 078 } 079 080 imageOrg0 = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE); 081 imageOrg1 = cvLoadImage(argv[2], CV_LOAD_IMAGE_GRAYSCALE); 082 if(imageOrg0 == NULL || imageOrg1 == NULL) { 083 fprintf(stderr, "Error: Can not open ImageFile(s)\n"); 084 exit(-1); 085 } 086 087 size = cvGetSize(imageOrg0); 088 sizeX = size.width; sizeY = size.height; 089 imagePha = cvCreateImage(size, IPL_DEPTH_64F, 1); 090 091 matComp0 = cvCreateMat(sizeY, sizeX, CV_64FC2); 092 matComp1 = cvCreateMat(sizeY, sizeX, CV_64FC2); 093 matReal = cvCreateMat(sizeY, sizeX, CV_64FC1); 094 matImag = cvCreateMat(sizeY, sizeX, CV_64FC1); 095 096 // (1) 2つの原画像をフーリエ変換し、空間周波数スペクトル(複素平面)を得る 097 myDftImage(imageOrg0, matComp0); 098 myDftImage(imageOrg1, matComp1); 099 100 // (2) 2つのスペクトルの合成積を取る(2つ目の複素平面は複素共役とする) 101 cvMulSpectrums(matComp0, matComp1, matComp0, CV_DXT_MUL_CONJ); 102 103 // (3) 合成積を振幅で正規化する 104 myNormalizeMat(matComp0, matComp0); 105 106 // (4) 合成積を逆離散フーリエ変換し、結果を実数配列と虚数配列に分解する 107 cvDFT(matComp0, matComp0, CV_DXT_INVERSE); 108 cvSplit(matComp0, matReal, matImag, NULL, NULL); 109 110 // (5) 第1象限と第3象限、第2象限と第4象限を入れ替える 111 cvShiftDFT(matReal, matReal); 112 113 // (6) 実数配列を正規化し、位相限定相関画像を得る 114 cvNormalize(matReal, imagePha, 0.0, 1.0, CV_MINMAX, NULL); 115 116 cvNamedWindow("Original Image0", CV_WINDOW_AUTOSIZE); 117 cvNamedWindow("Original Image1", CV_WINDOW_AUTOSIZE); 118 cvNamedWindow("Phase Image", CV_WINDOW_AUTOSIZE); 119 120 cvShowImage("Original Image0", imageOrg0); 121 cvShowImage("Original Image1", imageOrg1); 122 cvShowImage("Phase Image", imagePha); 123 124 cvWaitKey(0); 125 126 cvDestroyWindow("Original Image0"); 127 cvDestroyWindow("Original Image1"); 128 cvDestroyWindow("Phase Image"); 129 cvReleaseImage(&imageOrg0); 130 cvReleaseImage(&imageOrg1); 131 cvReleaseImage(&imagePha); 132 cvReleaseMat(&matReal); 133 cvReleaseMat(&matImag); 134 135 exit(0); 136 } 137 138 void cvShiftDFT(CvArr *src_arr, CvArr *dst_arr) { 139 CvMat *tmp = 0; 140 CvMat q1stub, q2stub; 141 CvMat q3stub, q4stub; 142 CvMat d1stub, d2stub; 143 CvMat d3stub, d4stub; 144 CvMat *q1, *q2, *q3, *q4; 145 CvMat *d1, *d2, *d3, *d4; 146 147 CvSize size = cvGetSize(src_arr); 148 CvSize dst_size = cvGetSize(dst_arr); 149 int cx, cy; 150 151 if(dst_size.width != size.width || dst_size.height != size.height) { 152 cvError(CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", __FILE__, __LINE__); 153 } 154 155 if(src_arr == dst_arr) { 156 tmp = cvCreateMat(size.height / 2, size.width / 2, cvGetElemType(src_arr)); 157 } 158 cx = size.width / 2; 159 cy = size.height / 2; 160 161 q1 = cvGetSubRect(src_arr, &q1stub, cvRect(0, 0, cx, cy)); 162 q2 = cvGetSubRect(src_arr, &q2stub, cvRect(cx, 0, cx, cy)); 163 q3 = cvGetSubRect(src_arr, &q3stub, cvRect(cx, cy, cx, cy)); 164 q4 = cvGetSubRect(src_arr, &q4stub, cvRect(0, cy, cx, cy)); 165 d1 = cvGetSubRect(src_arr, &d1stub, cvRect(0, 0, cx, cy)); 166 d2 = cvGetSubRect(src_arr, &d2stub, cvRect(cx, 0, cx, cy)); 167 d3 = cvGetSubRect(src_arr, &d3stub, cvRect(cx, cy, cx, cy)); 168 d4 = cvGetSubRect(src_arr, &d4stub, cvRect(0, cy, cx, cy)); 169 170 if(src_arr != dst_arr) { 171 if(!CV_ARE_TYPES_EQ(q1, d1)) { 172 cvError(CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__); 173 } 174 cvCopy(q3, d1, 0); 175 cvCopy(q4, d2, 0); 176 cvCopy(q1, d3, 0); 177 cvCopy(q2, d4, 0); 178 } else { 179 cvCopy(q3, tmp, 0); 180 cvCopy(q1, q3, 0); 181 cvCopy(tmp, q1, 0); 182 cvCopy(q4, tmp, 0); 183 cvCopy(q2, q4, 0); 184 cvCopy(tmp, q2, 0); 185 } 186 187 return; 188 }