pgm2dctbindata.cc

  1 const char *help = "\
  2 progname: pgm2dctbindata.cc\n\
  3 code2html: This program reads a pgm image and decomposes it in DCT/DCTmod2 blocks.\n\
  4 version: Torch3 vision2.0, 2004-2005\n\
  5 (c) Sebastien Marcel (marcel@idiap.ch)\n";
  6 
  7 #include "ImageGray.h"
  8 #include "ipDCT2D.h"
  9 #include "ipBlock.h"
 10 #include "ipDCTmod2.h"
 11 #include "DiskXFile.h"
 12 #include "CmdLine.h"
 13 
 14 using namespace Torch;
 15 
 16 // Allowed dimension for DCT mod2 (from Conrad Sanderson)
 17 const int allowed_dim[] = {6, 10, 15, 21, 28, 36, 43, 49, 54, 58, 61, 63, 64};
 18 
 19 int main(int argc, char *argv[])
 20 {
 21 	char *filename_in;
 22 	char *filename_out;
 23 	int dct_dim;
 24 	int delta_neighbour;
 25 	int delta_keep;
 26 	int block_size;
 27 	int block_overlap;
 28 	bool block_to_frame;
 29 	bool dctmod2;
 30 	bool overide;
 31 	bool verbose;
 32 	bool display;
 33 
 34 	
 35 	CmdLine cmd;
 36 	cmd.setBOption("write log", false);
 37 	cmd.info(help);
 38 	cmd.addText("\nArguments:");
 39 	cmd.addSCmdArg("imagefile in", &filename_in, "image file in");
 40 	cmd.addICmdArg("DCT dim", &dct_dim, "DCT 2D dimension");
 41 	cmd.addSCmdArg("output filename", &filename_out, "output bindata filename");
 42 	cmd.addText("\nOptions:");
 43 	cmd.addBCmdOption("-blocktoframe", &block_to_frame, false, "a block becomes a frame");
 44 	cmd.addICmdOption("-block", &block_size, 8, "block size");
 45 	cmd.addICmdOption("-overlap", &block_overlap, 4, "block overlap");
 46 	cmd.addICmdOption("-delta", &delta_neighbour, 1, "delta neighbour");
 47 	cmd.addICmdOption("-deltakeep", &delta_keep, 3, "delta keep");
 48 	cmd.addBCmdOption("-dctmod2", &dctmod2, false, "apply dctmod2");
 49 	cmd.addBCmdOption("-overide", &overide, false, "overide 8x8 dctmod2");
 50 	cmd.addBCmdOption("-verbose", &verbose, false, "verbose");
 51 	cmd.addBCmdOption("-display", &display, false, "display dct features");
 52 	cmd.read(argc, argv);
 53 	
 54 	//
 55 	if(verbose) print("DCT 2D feature extraction.\n");
 56 
 57 	if((dctmod2 == true) && (block_size != 8))
 58 	{
 59 		warning("DCTmod2 is usually designed only for 8x8 blocks.");
 60 		
 61 		if(overide == false) 
 62 		{
 63 			print("Disabling dctmod2.\n");
 64 
 65 		   	dctmod2 = false;
 66 		}
 67 	}
 68 
 69 	if(dctmod2 == true)
 70 	{
 71 		int dim_ok = 0;
 72 		int max_ = sizeof(allowed_dim)/sizeof(int);
 73 		
 74 		for(int i = 0 ; i < max_ ; i++)
 75 			if(dct_dim == allowed_dim[i]) dim_ok = 1;
 76 	
 77 		if(!dim_ok)
 78 		{
 79 		   	error("DCT dim (%d) is incorrect.", dct_dim);
 80 		   	print("   Correct values are: ");
 81 			for(int i = 0 ; i < max_ ; i++)
 82 			   	print("%d ", allowed_dim[i]);
 83 	  		print("\n");
 84 	
 85 			exit(0);
 86 		}
 87 	}
 88   	
 89 	//
 90 	int n_inputs;
 91 	int n_patterns;
 92 	DiskXFile *pf_out;
 93 
 94 	// Load the image
 95 	ImageGray *grayimage;   
 96 	grayimage = new ImageGray();   
 97 	grayimage->load(filename_in);   
 98 
 99 	// feature image machine to apply for each block
100 	ipCore *ip = NULL;
101 	
102 		
103 	int n_block, n_output;
104 	// Choose the block by block convolution
105 	if(dctmod2 == true)
106 	{
107 		ip = new ipDCTmod2(grayimage->width, grayimage->height, "gray", dct_dim, block_size, block_overlap, delta_neighbour, delta_keep);
108 
109 		ipDCTmod2 *ip_ = (ipDCTmod2 *)ip;
110 		n_block = ip_->n_block;
111 		n_output = ip_->output_size;
112 	}
113 	else
114 	{
115 		ipCore *ip_dct = new ipDCT2D(block_size, "gray", dct_dim);
116 		ip_dct->setBOption("verbose", verbose);
117 
118 		ip = new ipBlock(grayimage->width, grayimage->height, "gray", ip_dct, dct_dim, block_size, block_overlap);
119 
120 		ipBlock *ip_ = (ipBlock *)ip;
121 		n_block = ip_->n_block;
122                 n_output = dct_dim;
123 	}
124 	ip->setBOption("verbose", verbose);
125 	
126 	if(verbose)
127 	{
128 		print("-> n_block = %d\n", n_block);
129 		print("-> n_output = %d\n", n_output);
130 	}
131 	
132 	//
133 	pf_out = new DiskXFile(filename_out, "w");
134 	if(pf_out == NULL)
135 	{
136   		error("Opening bindata file %s", filename_out);      
137     		return 0;
138 	}
139 	
140 	//
141 	if(block_to_frame)
142 	{
143 		if(verbose)
144 	  		print("Block to frame: each block becomes a frame.\n");
145 		
146 		n_inputs = n_output;
147 		n_patterns = n_block;
148 	}
149 	else
150 	{
151 		n_inputs = n_block * n_output;
152 		n_patterns = 1;
153 	}
154 
155 	if(verbose)
156 	{
157 		print("Output file ...\n");
158 		print("   n_inputs = %d\n", n_inputs);
159 		print("   n_patterns = %d\n", n_patterns);  
160 	}
161 
162 	pf_out->write(&n_patterns, sizeof(int), 1);
163 	pf_out->write(&n_inputs, sizeof(int), 1);
164 	
165 	//
166 	float *data_out = new float [n_inputs];
167 
168 	
169 	// Apply the pattern machine (DCT) to each block of the image
170 	ip->process(grayimage);
171 
172 	if(block_to_frame)
173 	{
174 		for(int b = 0 ; b < n_block ; b++)
175 		{
176 		   	if(display == true) print("Block %d: ", b);
177 			
178 			real *output_ = ip->seq_out->frames[b];
179 			
180 			for(int i = 0 ; i < n_output ; i++)
181 			{
182 		   		if(display == true) print("%g ", output_[i]);
183 
184 		   		data_out[i] = output_[i];
185 			}
186 
187 		   	if(display == true) print("\n");
188 		
189 			for(int i = 0 ; i <  n_inputs ; i++)
190 				pf_out->write(&data_out[i], sizeof(float), 1);   
191 		}
192 	}
193 	else
194 	{
195 		int j = 0;
196 		
197 		for(int b = 0 ; b < n_block ; b++)
198 		{
199 		   	if(display == true) print("Block %d: ", b);
200 			
201 			real *output_ = ip->seq_out->frames[b];
202 			
203 			for(int i = 0 ; i < n_output ; i++)
204 			{
205 		   		if(display == true) print("%g ", output_[i]);
206 
207 		   		data_out[j] = output_[i];
208 				
209 				j++;
210 			}
211 		   	if(display == true) print("\n");
212 		}
213 		
214 		for(int i = 0 ; i <  n_inputs ; i++)
215 			pf_out->write(&data_out[i], sizeof(float), 1);   
216 	}
217 
218 	delete [] data_out;
219 	delete pf_out;
220 	
221 
222 	// Free all
223 	delete ip;
224 	delete grayimage;
225 
226 	return 0;
227 }