2011-10-17 21 views
7

मैं http://www.fftw.org/ से लाइब्रेरी का उपयोग कर एक छवि को एफएफटी करने की कोशिश कर रहा हूं ताकि मैं आवृत्ति डोमेन में एक रूपांतरण कर सकूं। लेकिन मैं यह नहीं समझ सकता कि इसे कैसे काम करना है। यह समझने के लिए कि मैं कैसे एक छवि को पिक्सेल रंगों की एक सरणी के रूप में एफएफटी अग्रेषित करने की कोशिश कर रहा हूं और उसके बाद पिक्सेल रंगों की एक ही सरणी प्राप्त करने के लिए पिछड़ा एफएफटी। यहाँ मैं क्या करना है:फॉरवर्ड एफएफटी एक छवि और पिछड़ा एफएफटी एक ही परिणाम प्राप्त करने के लिए एक छवि

fftw_plan planR, planG, planB; 
fftw_complex *inR, *inG, *inB, *outR, *outG, *outB, *resultR, *resultG, *resultB; 

//Allocate arrays. 
inR = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 
inG = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 
inB = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 

outR = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 
outG = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 
outB = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 

resultR = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 
resultG = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 
resultB = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width); 

//Fill in arrays with the pixelcolors. 
for (int y = 0; y < height; y++) { 
    for (int x = 0; x < width; x++) { 
     int currentIndex = ((y * width) + (x)) * 3; 
     inR[y * width + x][0] = pixelColors[currentIndex]; 
     inG[y * width + x][0] = pixelColors[currentIndex + 1]; 
     inB[y * width + x][0] = pixelColors[currentIndex + 2]; 
    } 
} 

//Forward plans. 
planR = fftw_plan_dft_2d(width, width, inR, outR, FFTW_FORWARD, FFTW_MEASURE); 
planG = fftw_plan_dft_2d(width, width, inG, outG, FFTW_FORWARD, FFTW_MEASURE); 
planB = fftw_plan_dft_2d(width, width, inB, outB, FFTW_FORWARD, FFTW_MEASURE); 

//Forward FFT. 
fftw_execute(planR); 
fftw_execute(planG); 
fftw_execute(planB); 

//Backward plans. 
planR = fftw_plan_dft_2d(width, width, outR, resultR, FFTW_BACKWARD, FFTW_MEASURE); 
planG = fftw_plan_dft_2d(width, width, outG, resultG, FFTW_BACKWARD, FFTW_MEASURE); 
planB = fftw_plan_dft_2d(width, width, outB, resultB, FFTW_BACKWARD, FFTW_MEASURE); 

//Backward fft 
fftw_execute(planR); 
fftw_execute(planG); 
fftw_execute(planB); 

//Overwrite the pixelcolors with the result. 
for (int y = 0; y < height; y++) { 
    for (int x = 0; x < width; x++) { 
     int currentIndex = ((y * width) + (x)) * 3; 
     pixelColors[currentIndex] = resultR[y * width + x][0]; 
     pixelColors[currentIndex + 1] = resultG[y * width + x][0]; 
     pixelColors[currentIndex + 2] = resultB[y * width + x][0]; 
    } 
} 

कोई मुझे कैसे FFT एक छवि और फिर पिछड़े FFT FFTW का उपयोग कर एक ही परिणाम प्राप्त करने के लिए छवि को अग्रेषित करने का एक उदाहरण दिखा सकते हैं? मैं कई उदाहरण देख रहा हूं कि एफएफटीडब्ल्यू को एफएफटी में कैसे उपयोग किया जाए, लेकिन मैं यह नहीं समझ सकता कि यह मेरी स्थिति पर कैसे लागू होता है जहां मेरे पास छवि का प्रतिनिधित्व करने वाले पिक्सेल रंगों की एक श्रृंखला है।

उत्तर

15

जब आप आगे एफएफटी के बाद एफएफटी आगे करते हैं तो ध्यान देने योग्य एक महत्वपूर्ण बात यह है कि आम तौर पर अंतिम परिणाम पर एन लागू होने के स्केलिंग कारक में परिणाम होता है, यानी परिणामी छवि पिक्सेल मानों को एन द्वारा विभाजित करने की आवश्यकता होगी मूल पिक्सेल मानों से मेल खाने के लिए ऑर्डर करें। (एन FFT के आकार जा रहा है।) तो अपने उत्पादन पाश शायद कुछ इस तरह दिखना चाहिए:

//Overwrite the pixelcolors with the result. 
for (int y = 0; y < height; y++) { 
    for (int x = 0; x < width; x++) { 
     int currentIndex = ((y * width) + (x)) * 3; 
     pixelColors[currentIndex] = resultR[y * width + x][0]/(width * height); 
     pixelColors[currentIndex + 1] = resultG[y * width + x][0]/(width * height); 
     pixelColors[currentIndex + 2] = resultB[y * width + x][0]/(width * height); 
    } 
} 

भी ध्यान रखें कि आप शायद एक असली करने के लिए जटिल FFT एक जटिल-हैं- के बाद क्या करना चाहते हैं असली आईएफएफटी (स्मृति और प्रदर्शन दोनों के मामले में कुछ और अधिक कुशल)। अभी के लिए ऐसा लगता है कि आप दोनों दिशाओं में जटिल-जटिल हैं, जो ठीक है, लेकिन आप अपने इनपुट सरणी को सही तरीके से भर नहीं रहे हैं। आप के साथ जटिल-से-जटिल तो आप शायद कुछ इस तरह करने के लिए अपने इनपुट पाश बदलना चाहते रहना जा रहे हैं:

//Fill in arrays with the pixelcolors. 
for (int y = 0; y < height; y++) { 
    for (int x = 0; x < width; x++) { 
     int currentIndex = ((y * width) + (x)) * 3; 
     inR[y * width + x][0] = (double)pixelColors[currentIndex]; 
     inR[y * width + x][1] = 0.0; 
     inG[y * width + x][0] = (double)pixelColors[currentIndex + 1]; 
     inG[y * width + x][1] = 0.0; 
     inB[y * width + x][0] = (double)pixelColors[currentIndex + 2]; 
     inB[y * width + x][1] = 0.0; 
    } 
} 

यानी पिक्सेल मान जटिल इनपुट मानों और के वास्तविक भागों में जाना काल्पनिक भागों को शून्य करने की आवश्यकता है।

ध्यान देने योग्य एक और बात: जब आप अंततः यह काम करते हैं तो आपको लगता है कि प्रदर्शन भयानक है - वास्तविक एफएफटी के लिए किए गए समय के सापेक्ष एक योजना बनाने में काफी समय लगता है। विचार यह है कि आप केवल एक बार योजना बनाते हैं, लेकिन कई एफएफटी करने के लिए इसका इस्तेमाल करते हैं। तो आप वास्तविक एफएफटी कोड से योजना निर्माण को अलग करना चाहते हैं और इसे प्रारंभिक दिनचर्या या कन्स्ट्रक्टर या जो कुछ भी डाल सकते हैं।

2

लेकिन यदि आप realToComplex या ComplexToRealFunction का उपयोग इस तथ्य पर ध्यान देते हैं कि छवि आयामों [ऊंचाई x (चौड़ाई/2 +1)] के मैट्रिक्स में संग्रहीत की जाएगी और यदि आप कुछ मध्यवर्ती गणना करना चाहते हैं आवृत्ति डोमेन, वे थोड़ा कठिन हो जाएगा ...

संबंधित मुद्दे