⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fourierdescriptor.c

📁 完整的3D 模型检索程序
💻 C
字号:
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <windows.h>

#include "fftw/rfftw.h"

#include "ds.h"
#include "TraceContour.h"
#include "Thin.h"
#include "Bitmap.h"
#include "Morphology.h"

int IsMultiPart(unsigned char *ContourMask, unsigned char *Y, int width, int height)
{
	int		insideArea, outsideArea;
	int		i, j, k, change, total;
	int		MaskCoor[4] = {-1, 1, -width, width};

	total = width * height;

	// inside: 0; contour: 255; outside: 128
	for(i=0; i<width; i++)
		ContourMask[i] = 128;
	for(i=total-width; i<total; i++)
		ContourMask[i] = 128;
	for(i=0; i<total; i+=width)
		ContourMask[i] = ContourMask[i+width-1] = 128;
	
	do
	{
		change = 0;

		// left-right, top-bottom
		for(j=width; j<total-width; j+=width)
			for(k=1; k<width-1; k++)
				if( ContourMask[j+k] == 0 )
					for(i=0; i<4; i++)
						if( ContourMask[j+k+MaskCoor[i]] == 128 )
						{
							ContourMask[j+k] = 128;
							change = 1;
						}
		// right-left, bottom-top
		for(j=total-2-width; j>0; j-=width)
			for(k=width-1; k>0; k--)
				if( ContourMask[j+k] == 0 )
					for(i=0; i<4; i++)
						if( ContourMask[j+k+MaskCoor[i]] == 128 )
						{
							ContourMask[j+k] = 128;
							change = 1;
						}

	}while( change );

//WriteBitmap8(ContourMask, width, height, "ttt2.bmp");

	// get area of contour area
	insideArea = outsideArea = 0;
	for(i=0; i<total; i++)
		if( Y[i] < 255 )
		{
			if( ContourMask[i] == 128 )
				outsideArea ++;
			else
				insideArea ++;
		}

	return ( (double)insideArea / (double)(insideArea+outsideArea) > 0.95 ) ? 0 : 1;
}

// *Y: 255 is background
// input is an edge image
void FourierDescriptor(double FdCoeff[], unsigned char *Y, int width, int height, 
					   sPOINT *Contour, unsigned char *ContourMask, double CenX, double CenY)
{
	int				total, i, k, N;//, cenx, ceny;
	fftw_real		*CenDist;	// the contour is the input of fourier descriptor
    rfftw_plan		p;
	fftw_real		*out, *power_spectrum;
	int				num;
	unsigned char	*Buff;
	unsigned char	*flag;	// use for another mask in Thin()
	POINT			Size={width, height};
//FILE *fpt;
//fpt = fopen("testfd.txt", "w");
//for(i=0; i<width*height; i++)
//	fprintf(fpt, "%d,", Y[i]);
//fclose(fpt);

	total = width * height;

//WriteBitmap8(Y, width, height, "tt1.bmp");
	num = TraceContour(Contour, ContourMask, Y, width, height);

//fpt = fopen("testtc.txt", "w");
//fprintf(fpt, "%d\n", num);
//for(i=0; i<num; i++)
//	fprintf(fpt, "%d\n", Contour[i].y*width+Contour[i].x);
//fclose(fpt);

//WriteBitmap8(ContourMask, width, height, "tt2.bmp");
	if( IsMultiPart(ContourMask, Y, width, height) )
	{
		Buff = (unsigned char*) malloc( total * sizeof(unsigned char));
		memcpy(Buff, Y, total * sizeof(unsigned char));
		BINARYErosion3x3(Buff, Size);
		// fix bug: IsMultiPart() should be run after TraceContour()
		TraceContour(Contour, ContourMask, Buff, width, height);
		if( IsMultiPart(ContourMask, Buff, width, height) )	// fix bug: should be "Buff" NOT "Y"
		{
			BINARYErosion5x5(Buff, Size);
			TraceContour(Contour, ContourMask, Buff, width, height);
			if( IsMultiPart(ContourMask, Buff, width, height) )	// fix bug: should be "Buff" NOT "Y"
			{
				memcpy(Buff, Y, total * sizeof(unsigned char));
				BoundingBox(Buff, Size);
			}
		}

		flag = (unsigned char *) malloc( total * sizeof(unsigned char));
//WriteBitmap8(Y, width, height, "t3.bmp");
		Thin(Buff, Y, flag, width, width*height);
//WriteBitmap8(Buff, width, height, "t4.bmp");

		num = TraceContour(Contour, ContourMask, Buff, width, height);
		free(Buff);
		free(flag);
	}
//WriteBitmap8(ContourMask, width, height, "ttt_1.bmp");

	if( num < 8 )
	{
//		printf("error!!\n");
		for(i=0; i<FD_COEFF_NO; i++)
			FdCoeff[i] = 0;
		return ;
	}

	CenDist = (fftw_real *) malloc( num * sizeof(fftw_real));
//	cenx = width / 2;
//	ceny = height / 2;
	for(i=0; i<num; i++)
//		CenDist[i] = (fftw_real) HYPOT(Contour[i].x-cenx, Contour[i].y-ceny);
//		CenDist[i] = (fftw_real) HYPOT(Contour[i].x-CENTER_X, Contour[i].y-CENTER_Y);
		CenDist[i] = (fftw_real) HYPOT(Contour[i].x-CenX, Contour[i].y-CenY);

//fpt = fopen("testCenDist.txt", "w");
//for(i=0; i<num; i++)
//	fprintf(fpt, "%f\n", CenDist[i]);
//fclose(fpt);

	// fft, get fourier descriptor from the contour
	N = num;
	out = (fftw_real *) malloc(N * sizeof(fftw_real));
	power_spectrum = (fftw_real *) malloc( (N/2+1) * sizeof(fftw_real));

	p = rfftw_create_plan(N, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
	rfftw_one(p, CenDist, out);

	// fix bug: The image part should be 0, not out[0]
	power_spectrum[0] = HYPOT(out[0],0);  // out[0]*out[0];  // DC component
	for (k = 1; k < (N+1)/2; ++k)  // (k < N/2 rounded up)
		power_spectrum[k] = HYPOT(out[k], out[N-k]);	// out[k]*out[k] + out[N-k]*out[N-k];
	if (N % 2 == 0) // N is even
		// fix bug: The image part should be 0, not out[N/2]
		power_spectrum[N/2] = HYPOT(out[N/2], 0);	// out[N/2]*out[N/2]; // Nyquist freq.

	rfftw_destroy_plan(p);

	N= N/2+1;		// fix bug: power_spectrum[0~N/2] only
	for(i=1; i<=FD_COEFF_NO; i++)
		if( i<N )
			FdCoeff[i-1] = power_spectrum[i]/power_spectrum[0];
		else
			FdCoeff[i-1] = 0;

//fpt = fopen("testps.txt", "w");
//for(i=0; i<(N+1)/2; i++)
//	fprintf(fpt, "%f\n", power_spectrum[i]);
//fclose(fpt);

//fpt = fopen("testfft.txt", "w");
//for(i=0; i<num; i++)
//	fprintf(fpt, "%f\n", out[i]);
//fclose(fpt);

//fpt = fopen("testfdcoeff.txt", "w");
//for(i=0; i<FD_COEFF_NO; i++)
//	fprintf(fpt, "%f\n", FdCoeff[i]);
//fclose(fpt);

	free(out);
	free(power_spectrum);
	free(CenDist);
	return;
}


/*
#include "rfftw.h"

#define N 10

void main()
{
	fftw_complex in[N]={{10,0},{8,0},{6,0},{4,0},{2,0},{4,0},{8,0},{12,0},{6,0},{0,0}}, *out;
	fftw_plan p;
	int	i;

	out = (fftw_complex *) malloc( N * sizeof(fftw_complex));

	p = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE);

	fftw_one(p, in, out);

	fftw_destroy_plan(p); 

	for(i=0; i<N; i++)
		printf("(%.3f, %.3f) ", out[i].re, out[i].im);
	printf("\n");

	for(i=0; i<N; i++)
		printf("%.3f ", out[i].re*out[i].re+out[i].im*out[i].im);
	printf("\n");

	free(out);
}
*/

/*
#define N 10

#include "rfftw.h"
void main()
{
	fftw_real in[N]={10,8,6,4,2,4,8,12,6,0}, out[N], power_spectrum[N/2+1];
     rfftw_plan p;
     int i, k;

     p = rfftw_create_plan(N, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);

     rfftw_one(p, in, out);
     power_spectrum[0] = out[0]*out[0];  // DC component
     for (k = 1; k < (N+1)/2; ++k)  // (k < N/2 rounded up)
          power_spectrum[k] = out[k]*out[k] + out[N-k]*out[N-k];
     if (N % 2 == 0) // N is even
          power_spectrum[N/2] = out[N/2]*out[N/2];  // Nyquist freq.

     rfftw_destroy_plan(p);

	for(i=0; i<N; i++)
		printf("%.3f ", out[i]);
	printf("\n");

	for(i=0; i<N/2+1; i++)
		printf("%.3f ", power_spectrum[i]);
	printf("\n");

}
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -