ThreeB 1.1
multispot5_jni.cc
Go to the documentation of this file.
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