ThreeB 1.1
|
00001 #include <sstream> 00002 #include <algorithm> 00003 #include <cvd/image.h> 00004 #include <cvd/image_convert.h> 00005 00006 #include "ThreeBRunner.h" 00007 #include "storm_imagery.h" 00008 #include "multispot5.h" 00009 #include "multispot5_place_choice.h" 00010 #include "utility.h" 00011 #include <gvars3/instances.h> 00012 00013 #include <tag/printf.h> 00014 #undef make_tuple 00015 #include <tr1/tuple> 00016 00017 using namespace std; 00018 using namespace std::tr1; 00019 using namespace CVD; 00020 using namespace GVars3; 00021 using namespace tag; 00022 using namespace TooN; 00023 00024 00025 /** 00026 3B User interface for the Java plugin. 00027 00028 This particular UI ferries various messages between Java and C++ 00029 via callbacks and polling. 00030 00031 @ingroup gPlugin 00032 */ 00033 class JNIUserInterface: public UserInterfaceCallback 00034 { 00035 private: 00036 JNIEnv *env; 00037 jobject ThreeBRunner_this; 00038 jmethodID send_message_string; 00039 jmethodID die; 00040 jmethodID should_stop; 00041 jmethodID send_new_points; 00042 int passes; 00043 00044 public: 00045 JNIUserInterface(JNIEnv* env_, jobject jthis) 00046 :env(env_),ThreeBRunner_this(jthis) 00047 { 00048 jclass cls = env->GetObjectClass(jthis); 00049 00050 send_message_string = env->GetMethodID(cls, "send_message_string", "(Ljava/lang/String;)V"); 00051 die = env->GetMethodID(cls, "die", "(Ljava/lang/String;)V"); 00052 00053 should_stop = env->GetMethodID(cls, "should_stop", "()Z"); 00054 00055 send_new_points = env->GetMethodID(cls, "send_new_points", "([F)V"); 00056 00057 passes = GV3::get<int>("main.passes"); 00058 } 00059 00060 00061 virtual void per_spot(int iteration, int pass, int spot_num, int total_spots) 00062 { 00063 send_message(sPrintf("Iteration %i, optimizing %4i%%", iteration*passes+pass, 100 *spot_num / total_spots)); 00064 } 00065 00066 virtual void per_modification(int iteration, int spot_num, int total_spots) 00067 { 00068 send_message(sPrintf("Iteration %i, modifying %4i%%", iteration*passes+passes-1, 100 *spot_num / total_spots)); 00069 } 00070 00071 virtual void per_pass(int , int , const std::vector<TooN::Vector<4> >& spots) 00072 { 00073 //Copy data into the correct format 00074 vector<jfloat> pts_data; 00075 for(unsigned int i=0; i < spots.size(); i++) 00076 { 00077 pts_data.push_back(spots[i][2]); 00078 pts_data.push_back(spots[i][3]); 00079 } 00080 00081 //Allocate a java array and copy data into it 00082 jfloatArray pts = env->NewFloatArray(pts_data.size()); 00083 env->SetFloatArrayRegion(pts, 0, pts_data.size(), pts_data.data()); 00084 00085 //Make the call... 00086 jvalue pts_obj; 00087 pts_obj.l = pts; 00088 00089 env->CallVoidMethod(ThreeBRunner_this, send_new_points, pts_obj); 00090 00091 //Free the object 00092 env->DeleteLocalRef(pts); 00093 } 00094 00095 virtual void perhaps_stop() 00096 { 00097 bool stop = env->CallBooleanMethod(ThreeBRunner_this, should_stop); 00098 if(stop) 00099 throw UserIssuedStop(); 00100 } 00101 00102 00103 void send_message(const string& s) 00104 { 00105 jvalue message_string; 00106 message_string.l = env->NewStringUTF(s.c_str()); 00107 env->CallVoidMethod(ThreeBRunner_this, send_message_string, message_string); 00108 env->DeleteLocalRef(message_string.l); 00109 } 00110 00111 void fatal(const string& s) 00112 { 00113 jvalue message_string; 00114 message_string.l = env->NewStringUTF(s.c_str()); 00115 env->CallVoidMethod(ThreeBRunner_this, die, message_string); 00116 env->DeleteLocalRef(message_string.l); 00117 } 00118 }; 00119 00120 ///Get a local C++ copy of a java string. 00121 ///@ingroup gPlugin 00122 string get_string(JNIEnv *env, jstring js) 00123 { 00124 const char* str; 00125 00126 //Covert the config into a string 00127 str = env->GetStringUTFChars(js, NULL); 00128 00129 string stdstring(str); 00130 env->ReleaseStringUTFChars(js, str); 00131 00132 00133 return stdstring; 00134 } 00135 00136 ///Get a local C++ copy of an image from a jbyteArray coming from the guts of ImageJ 00137 ///@ingroup gPlugin 00138 Image<jbyte> get_local_copy_of_image(JNIEnv* env, jbyteArray data, int rows, int cols) 00139 { 00140 //This takes a copy of the pixels (perhaps) 00141 jbyte* pix = env->GetByteArrayElements(data, NULL); 00142 00143 BasicImage<jbyte> pix_im(pix, ImageRef(cols, rows)); 00144 00145 Image<jbyte> im; 00146 im.copy_from(pix_im); 00147 00148 //This frees the pixels if copied, or releases a reference 00149 env->ReleaseByteArrayElements(data,pix, JNI_ABORT); 00150 00151 return im; 00152 } 00153 00154 ///Get a local C++ copy of an image from a jfloatArray coming from the guts of ImageJ 00155 ///@ingroup gPlugin 00156 Image<float> get_local_copy_of_image(JNIEnv* env, jfloatArray data, int rows, int cols) 00157 { 00158 //This takes a copy of the pixels (perhaps) 00159 float* pix = env->GetFloatArrayElements(data, NULL); 00160 00161 BasicImage<float> pix_im(pix, ImageRef(cols, rows)); 00162 00163 Image<float> im; 00164 im.copy_from(pix_im); 00165 00166 //This frees the pixels if copied, or releases a reference 00167 env->ReleaseFloatArrayElements(data,pix, JNI_ABORT); 00168 00169 return im; 00170 } 00171 00172 00173 ///Run the 3B code. 00174 ///@ingroup gPlugin 00175 JNIEXPORT void JNICALL Java_ThreeBRunner_call 00176 (JNIEnv *env, jobject jthis, jstring cfg, jobjectArray images, jbyteArray mask_data, jint n_images, jint rows, jint cols, jstring file) 00177 { 00178 istringstream config(get_string(env, cfg)); 00179 GUI.ParseStream(config); 00180 00181 JNIUserInterface ui(env, jthis); 00182 ui.send_message("Initializing..."); 00183 00184 string filename = get_string(env, file); 00185 00186 //Attmpt to open the file 00187 ofstream save_spots; 00188 save_spots.open(filename.c_str()); 00189 int err = errno; 00190 00191 if(!save_spots.good()) 00192 { 00193 ui.fatal("failed to open " + filename + ": " + strerror(err)); 00194 return; 00195 } 00196 00197 vector<ImageRef> maskir; 00198 Image<double> maskd; 00199 { 00200 Image<jbyte> mask = get_local_copy_of_image(env, mask_data, rows, cols); 00201 maskd = convert_image(mask); 00202 for(ImageRef p(-1, 0); p.next(mask.size()); ) 00203 if(mask[p]) 00204 maskir.push_back(p); 00205 } 00206 00207 00208 vector<Image<float> > ims; 00209 00210 for(int i=0; i < n_images; i++) 00211 { 00212 jfloatArray f = static_cast<jfloatArray>(env->GetObjectArrayElement(images, i)); 00213 ims.push_back(preprocess_image(get_local_copy_of_image(env, f, rows, cols))); 00214 env->DeleteLocalRef(f); 00215 } 00216 00217 double mean, variance; 00218 tie(mean, variance) = mean_and_variance(ims); 00219 00220 for(unsigned int i=0; i < ims.size(); i++) 00221 transform(ims[i].begin(), ims[i].end(), ims[i].begin(), bind1st(multiplies<double>(), 1/ sqrt(variance))); 00222 00223 tie(mean, variance) = mean_and_variance(ims); 00224 00225 //A sanity check. 00226 cerr << "Rescaled:\n"; 00227 cerr << "mean = " << mean << endl; 00228 cerr << "std = " << sqrt(variance) << endl; 00229 cerr << "Version 1.1" << endl; 00230 00231 00232 auto_ptr<FitSpotsGraphics> gr = null_graphics(); 00233 00234 place_and_fit_spots(ims, maskir, maskd, save_spots, *gr, ui); 00235 } 00236