gegl r2561 - branches/branch2_zhangjb/docs



Author: zhangjb
Date: Sun Aug  3 05:57:56 2008
New Revision: 2561
URL: http://svn.gnome.org/viewvc/gegl?rev=2561&view=rev

Log:


Added:
   branches/branch2_zhangjb/docs/frequency-domain-process-manual.txt

Added: branches/branch2_zhangjb/docs/frequency-domain-process-manual.txt
==============================================================================
--- (empty file)
+++ branches/branch2_zhangjb/docs/frequency-domain-process-manual.txt	Sun Aug  3 05:57:56 2008
@@ -0,0 +1,153 @@
+1. Write your first program using frequency-domain operations
+
+The "dft" operation transforms the time-domain image  into frenquency-domain, 
+and the "idft" do the reverse process. One image which is processed by "dft" 
+operation and then processed by "idft" operation will back to  the same one 
+as original without any lost. In the following example, first two GeglNode 
+objects are generated, which are "dft" opeation and "idft" operation 
+respectively. Then, link them and process. After this process, the original 
+image goes through "dft" to "idft" and then back to the original one.
+
+/****************code example begin****************/
+{
+  gchar    *file_name = "surfer.png";
+  GeglNode *gegl = gegl_node_new();
+  GeglNode *image = gegl_node_new_child(gegl,
+                                        "operation",
+                                        "load",
+                                        "path",
+                                        file_name,
+                                        NULL);
+  GeglNode *dft = gegl_node_new_child(gegl, "operation", "dft", NULL);
+  GeglNode *idft = gegl_node_new_child(gegl, "operation", "idft", NULL);
+  GeglNode *pre = gegl_node_new_child(gegl, "operation",
+                                      "preview-frequency", NULL);
+  GeglNode *save = gegl_node_new_child(gegl,
+                                       "operation",
+                                       "png-save",
+                                       "path",
+                                       "test_result.png",
+                                       NULL);
+  gegl_node_link_many(image, dft, idft, save, NULL);
+  gegl_node_process(save);
+}
+/****************code example end ****************/
+
+You can preview the frequency domain image by just replace the "idft" with "pre"
+ in the statement "gegl_node_link_many(image,dft,idft,save,NULL)". 
+
+2. Use Gaussian-Lowpass filter to blur an image.
+
+Generally speaking, the digital signal processing in frequency domain follows 
+this pattern:
+.-----.	     .---.     .------.     .----.     .-----.
+|image| -->  |dft| --> |filter| --> |idft| --> |image|
+.-----.      .---.     .------.     .----.     .-----.
+
+Take gaussian-lowpass filter as an example:
+
+There are two parameters of this operation. "cutoff" refers to the cut off 
+frequency. The higher cutoff frequency, the deutlicher the processed image. 
+The "flag" parameter is used to indicate which component of "RGBA" to be 
+processed. If only R component is selected to be processed, flag should be set 
+to 1000b, and G should be 100b, B should be 10b, A should be 1b, etc. You can 
+combine them by an OR operation. For example flag=14=1110b=1000b|100b|10b means
+ RGB components but A componet are not selected to be processed.
+
+/****************code example begin****************/
+{
+  gchar    *file_name = "surfer.png";
+  GeglNode *gegl = gegl_node_new();
+  GeglNode *image = gegl_node_new_child(gegl,
+                                        "operation",
+                                        "load",
+                                        "path",
+                                        file_name,
+                                        NULL);
+  GeglNode *dft = gegl_node_new_child(gegl, "operation", "dft", NULL);
+  GeglNode *idft = gegl_node_new_child(gegl,"operation","idft", NULL);
+  GeglNode *glpf_filter = gegl_node_new_child(gegl,"operation",
+                                              "lowpass-gaussian",
+                                              "cutoff",30,"flag",15,NULL);
+  GeglNode *save = gegl_node_new_child(gegl,
+                                       "operation",
+                                       "png-save",
+                                       "path",
+                                       "test_result.png",
+                                       NULL);
+  gegl_node_link_many(image,dft,glpf_filter,idft,save,NULL);
+  gegl_node_process(save);
+}
+/****************code example end****************/
+
+3. Introduction to frenquency-domain image processing.
+
+
+4. Design your own filter.
+Although we have provided many filters, but we can not provide all. The 
+operation "freq-general-filter" is for those users who want to use their own 
+filters. If you need a filter but we did not provide, you could design it by 
+yourself following below. 
+
+In fact, any filter is a complex-number matrix, and any processing in frequncy
+ domain is multiplying the matrix on the frequency domain image.
+The multiply here does not mean matrices multiplying. Take a m*n image for
+ example, our "multiply" is means:
+
+for x=1..m
+ for y=1..n
+   // Note the "*" here refers to complex-number multiply here.
+   new_image[m][n] = origin_image[m][n]*filter[m][n];  
+ end
+end
+
+But one important point is that the filter must be symmetric to ensure the the 
+reslut after idft is a real-number matrix(it's no sence if a image's pixel is a 
+complex-number). 
+Because the filter is symmetric, you need not to give the whole matrix. You just
+ need to give the left half of the filter.
+Here is an example of "ideal lowpass filter".
+The function of ideal lowpass filter is :
+H(u,v)=1 D(u,v)<=cutoff
+       0 D(u,v)> cutoff
+The D(u,v) means the distance between point(u,v) and the center of the image:
+(width/2,height/2),
+which can be easily gotten by sqrt((u-width/2)^2+(v-height/2)^2).
+Given we are going to process an image whose size is m*n. 
+So the filter should be a (m/2+1)*n matrix because of the symmetric. You should
+first allocated an gdouble array of (m/2+1)*n size. And we use one-demison
+array to store the matrix, so you must do a little transformation: 
+filter[y*(m/2+1)+x] = H[y][x];
+The following thing is trivial: compute the function value of H(u,v) at every
+point. Since the frequency domain image is a matrix of complex number, the
+filter should be given as a matrix of complex number two.
+Here is the code of a ideal-lowpass processing:
+/*********************************code exampel begin**************************/
+{
+ gdouble *Hr = gnew0(gdouble,(m/2+1)*n); // Hr is the real componet of the filter
+ gdouble *Hi = gnew0(gdouble,(m/2+1)*n); // Hi is the image componet
+ 
+ for(y=0;y<height;y++)
+   for(x=0;x<(m/2+1);x++)
+    {
+         if(((y-height/2+1)*(y-height/2+1)+(x-width/2+1)*(x-width/2+1))<cutoff*cutoff) 
+             Hr[y*FFT_HALF(width)+x] = 1;
+	     
+    } 
+
+ GeglNode *filter = gegl_node_new_child(gegl, "operation",
+                                        "freq-general-filter","realH",
+                                        Hr, "imagH", Hi,"flag",14, NULL);
+  GeglNode *dft = gegl_node_new_child(gegl, "operation", "dft", NULL);
+  GeglNode *idft = gegl_node_new_child(gegl,"operation","idft", NULL);
+  GeglNode *save = gegl_node_new_child(gegl,
+                                       "operation",
+                                       "png-save",
+                                       "path",
+                                       "test_result.png",
+                                       NULL);
+  gegl_node_link_many(image,dft,glpf_filter,idft,save,NULL);
+  gegl_node_process(save);
+
+}
+/*********************************code exampel end****************************/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]