Loading src/TriangleMesh.cpp +124 −44 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ #undef max //some debug-code enabling triggers //#define SAVE_INTERMEDIATE_IMAGES #define SAVE_INTERMEDIATE_IMAGES #define TEXTURE_QUANTIZATION 64 #define TEXTURE_QUANTIZATION 8 #define SQR(x) ((x)*(x)) #define SKIP GetRandomUniform(0.0, 1.0) //'multiple' should be ideally 10^desired_decimal_accuracy int inline RoundTo(const float val, const float multiple=1000.f) { Loading Loading @@ -1509,16 +1511,17 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) i3d::Image3d<float> perlinInner,perlinOutside; perlinInner.CopyMetaData(mask); // DoPerlin3D(perlinInner,5.0,0.8*1.5,0.7*1.5,6); DoPerlin3D(perlinInner,1.0,0.8*1.3,0.7*1.5,6); DoPerlin3D(perlinInner,1.0,0.3,1.0,6); Stretch(perlinInner, 0.0f, 1.0f, 4.0f); #ifdef SAVE_INTERMEDIATE_IMAGES //perlinInner.SaveImage("2_PerlinAlone_Inner.ics"); perlinInner.SaveImage("2_PerlinAlone_Inner.ics"); #endif perlinOutside.CopyMetaData(mask); DoPerlin3D(perlinOutside,1.4,0.8*1.1,0.7*1.5,6); DoPerlin3D(perlinOutside,2.5,0.2,1.0,6); Stretch(perlinOutside, 0.0f, 1.0f, 2.0f); #ifdef SAVE_INTERMEDIATE_IMAGES //perlinOutside.SaveImage("2_PerlinAlone_Outside.ics"); perlinOutside.SaveImage("2_PerlinAlone_Outside.ics"); #endif i3d::Image3d<i3d::GRAY16> erroded; Loading @@ -1530,23 +1533,37 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) const float* pI=perlinInner.GetFirstVoxelAddr(); const float* pO=perlinOutside.GetFirstVoxelAddr(); const i3d::GRAY16* er=erroded.GetFirstVoxelAddr(); // intensity values const float innerBg = 0.0; const float innerPerlinStrength = 20.0f; const float coronaBg = 1.0f; const float coronaPerlinStrength = 330.0f; // distances (in microns) const float coronaWidth = 0.1f; const float interfaceCoronaInterior = 0.05f; while (p != pL) { //are we within the mask? if (*p > 0.f) { //close to the surface? if (*p < 0.2f || *er == 0) *p=1000.f + 5000.f*(*pO); //corona else if (*p < 0.4f) if (*p < coronaWidth || *er == 0) *p=coronaBg + coronaPerlinStrength*(*pO); // corona else if (*p < (coronaWidth + interfaceCoronaInterior)) { float factor = (*p - 0.2f)/(0.2f); *p=(300.f + 600.f*(*pI))*factor + (1000.f + 5000.f*(*pO))*(1.0f-factor); // linear interpolation factor (between corona and interior) float factor = (*p - coronaWidth)/(interfaceCoronaInterior); *p=(innerBg + innerPerlinStrength*(*pI))*factor + (coronaBg + coronaPerlinStrength*(*pO))*(1.0f-factor); } else *p=300.f + 600.f*(*pI); //inside *p=innerBg + innerPerlinStrength*(*pI); //inside if (*er == 0) *p=1500.f; //corona if (*er == 0) *p=coronaBg; //corona envelope (was 1500) if (*p < 0.f) *p=0.f; } Loading Loading @@ -1576,7 +1593,7 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) for (int z=0; z < (signed)dt.GetSizeZ(); ++z) for (int y=0; y < (signed)dt.GetSizeY(); ++y) for (int x=0; x < (signed)dt.GetSizeX(); ++x, ++p) for (int v=0; v < *p; v+=TEXTURE_QUANTIZATION) for (int v=0; v < floorf(*p); v+=TEXTURE_QUANTIZATION) { //convert px coords into um, use centres of voxels const float X=(float(x)+0.5f)/xRes + xOff; Loading @@ -1599,6 +1616,11 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsigned int idx) { // get the resolution of image i3d::Vector3d<float> res = mask.GetResolution().GetRes(); float max_res = std::max(res.x, std::max(res.y, res.z)); // ... pixels/micron const int density = 10; // ... how may dots should be pressed between two neighbouring pixel positions //syntactic short-cut to the proper filopodium geometry data mesh_t& filoMesh=Ftree[idx]; Loading @@ -1610,10 +1632,14 @@ void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsig const Vector3F& fP=filoMesh.fPoints[filoMesh.segFromPoint[i]]; const Vector3F& tP=filoMesh.fPoints[filoMesh.segToPoint[i]]; const float length=(tP-fP).Len(); //full segment has length = 0.005 const float length=(tP-fP).Len(); // segment length in microns // discrete stepping const int S = (int) ceil(length * max_res * density); /// OBSOLETE - with magic factor //stepping along the axis const int S=(int)ceil(5.f*length/0.005); //"fraction factor" // const int S=(int)ceil(5.f*length/0.005); //"fraction factor" for (int s=0; s < S; ++s) { Loading @@ -1631,8 +1657,15 @@ void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsig Vector3F p =fS*fP; p+=tS*tP; // OBSOLETE - magic factor //insert fl. dots float dotsCount=400000.f*r; // float dotsCount=400000.f*r; // the number of dots should correspond the width (radius) of filopodium // multiplied by given density. The density should be a large number as the // radius is typically very small const int dotDensity = 5; float dotsCount = dotDensity*r; // prevent data overflow (5 - multiplicity of addition) int upper_limit = std::numeric_limits<i3d::GRAY16>::max() / (5 * TEXTURE_QUANTIZATION); Loading @@ -1650,21 +1683,29 @@ void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsig Mul(mainDirection, vector2, vector4); // make them as small as the size of the radius in the given position vector1 *= r / vector1.Len(); vector2 *= r / vector2.Len(); vector3 *= r / vector3.Len(); vector4 *= r / vector4.Len(); vector1 /= vector1.Len(); vector2 /= vector2.Len(); vector3 /= vector3.Len(); vector4 /= vector4.Len(); int radiusInPixels = (int) ceil(r*max_res); for (int q=0; q < qM; ++q) { dots_filo.push_back(p); //dots_filo.push_back(p+Vector3F(0.0f,0.0f,+100*r)); //dots_filo.push_back(p+Vector3F(0.0f,0.0f,-100*r)); dots_filo.push_back(p+vector1); dots_filo.push_back(p+vector2); dots_filo.push_back(p+vector3); dots_filo.push_back(p+vector4); // The following cycle guarantees, that the dots will fill the filopodium // smoothly - from the center to the outer envelope. for (int step=0; step<=radiusInPixels; step++) { // how much the given vector should enlarge float scale = (r*(step+1.0f))/(radiusInPixels+1.0f); dots_filo.push_back(p+scale*vector1); dots_filo.push_back(p+scale*vector2); dots_filo.push_back(p+scale*vector3); dots_filo.push_back(p+scale*vector4); } } } } Loading Loading @@ -1868,10 +1909,6 @@ void PopulateCube(i3d::Image3d<i3d::GRAY16>& texture, { const int X=int(x-0.5f+float(ix)/float(xn)); ++T[X]; //DAVID: tady nepricitat +1, ale +GetRandomGauss(40.f,40.f/2.5f) //DAVID: ( za predpokladu, ze GetRandomGauss(mean,variance) ) //DAVID: variance nastavena zamerne s malym prekryvem //DAVID: pozor na pretekani intervalu GRAY16 //std::cout << "populating at [" << X << "," << Y << "," << Z << "]\n"; } Loading Loading @@ -1996,9 +2033,11 @@ void ActiveMesh::PhaseII(const i3d::Image3d<i3d::GRAY16>& texture, for (int y=0; y < (signed)blurred_texture.GetSizeY(); ++y) for (int x=0; x < (signed)blurred_texture.GetSizeX(); ++x, ++p) { // background signal: // max distance float maxDist = SQR((float)xC) + SQR((float)yC); // background signal (inverted parabola) float distSq = -(SQR((float)(x-xC)) + SQR((float)(y-yC)))/24200.f + 1.f; -(SQR((float)(x-xC)) + SQR((float)(y-yC)))/maxDist + 1.f; *p *= distSq; } #ifdef SAVE_INTERMEDIATE_IMAGES Loading @@ -2009,33 +2048,74 @@ void ActiveMesh::PhaseII(const i3d::Image3d<i3d::GRAY16>& texture, void ActiveMesh::PhaseIII(i3d::Image3d<float>& blurred, i3d::Image3d<i3d::GRAY16>& texture) { // NONSPECIFIC BACKGROUND i3d::Image3d<float> bgImg; bgImg.CopyMetaData(blurred); DoPerlin3D(bgImg,10.0,7.0,1.0,10); // very smooth a wide coherent noise // reset the maximum and minimin intesity levels of the background // to the expected values const float oldMaxI = bgImg.GetVoxelData().max(); const float oldMinI = bgImg.GetVoxelData().min(); const float newMaxI = 2.2f; const float newMinI = 2.0f; const float scale = (newMaxI-newMinI)/(oldMaxI-oldMinI); for (size_t i=0; i<bgImg.GetImageSize(); i++) { float value = bgImg.GetVoxel(i); value = scale*(value - oldMinI) + newMinI; bgImg.SetVoxel(i, value); } // given gain of EMCCD camera const int EMCCDgain = 1000; float* p=blurred.GetFirstVoxelAddr(); for (size_t i=0; i<blurred.GetImageSize(); i++, p++) { // shift the signal (simulates non-ideal black background) // ?reflection of medium? *p+=10.0f; *p+=bgImg.GetVoxel(i); // ENF ... Excess Noise Factor (stochasticity of EMCCD gain) // source of information: // https://www.qimaging.com/resources/pdfs/emccd_technote.pdf const float ENF = GetRandomUniform(1.0f, 1.4f); // PHOTON NOISE // uncertainty in the number of incoming photons // from statistics: shot noise = sqrt(signal) // from statistics: shot noise mean = sqrt(signal) const float noiseMean = sqrtf(*p); // for Poisson distribution E(X) = D(X) const float noiseVar = noiseMean; // SKIP avoid strong discretization of intenzity histogram due // to the Poisson probabilty function *p += ENF * ((float)GetRandomPoisson(noiseMean) - noiseMean + SKIP); *p+=40.f*((float)GetRandomPoisson(noiseMean) - noiseVar); //DAVID: tady odstranit 40.0f*, cili uz nenasobit //DAVID: bude asi nutne preladit vsechny Bulharske konstanty // EMCCD GAIN // amplification of signal (and inevitably also the noise) *p *= EMCCDgain; // DARK CURRENT // constants are parameters of Andor iXon camera provided from vendor: *p+=(float)GetRandomPoisson(0.06f); *p += ENF*EMCCDgain*(float)GetRandomPoisson(0.06f); // BASELINE (camera electron level) *p += 400.0f; // READOUT NOISE // variance up to 25.f (old camera on ILBIT) // variance about 1.f (for the new camera on ILBIT) *p+=GetRandomGauss(450.f,10.f); *p+=GetRandomGauss(0.0f,1.0f); // ADC (analogue-digital converter) // ADCgain ... how many electrons correcpond one intensity value // ADCoffset ... how much intensity levels are globally added to each pixel const float ADCgain = 28.0f; *p/=ADCgain; const float ADCoffset = 400.0f; *p+=ADCoffset; } #ifdef SAVE_INTERMEDIATE_IMAGES blurred.SaveImage("6_texture_finalized.ics"); Loading src/TriangleMesh.h +2 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ class ActiveMesh void PopulateSurfTriangles_Ftree(const unsigned int idx,const bool enforce=false); ///renders filopodium first aside, then overlays the given mask void RenderMask_filo(i3d::Image3d<i3d::GRAY16>& mask,const unsigned int idx,const bool showTriangles=false); void RenderMask_filo(i3d::Image3d<i3d::GRAY16>& mask,const unsigned int idx, const unsigned short color=100,const bool showTriangles=false); /// render directly into mask using volumetric mesh void RenderMask_bodyVol(i3d::Image3d<i3d::GRAY16>& mask,const bool showTriangles=false); Loading src/main_Generator.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ int main(int argc,char **argv) //translating all mesh points, to assure the meshes appear within //the produced images mesh.meshShift=minBB -Vector3F(1.0f); mesh.meshPlaygroundSize=(maxBB-minBB) +Vector3F(2.0f); mesh.meshPlaygroundSize=(maxBB-minBB) +Vector3F(5.0f); //NB: We also introduce 1um thick border around the mesh std::cout << "corners of a detected bounding box (with 1um thick border):\n"; std::cout << "[" << minBB.x << "," << minBB.y << "," << minBB.z << "] <-> [" Loading Loading
src/TriangleMesh.cpp +124 −44 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ #undef max //some debug-code enabling triggers //#define SAVE_INTERMEDIATE_IMAGES #define SAVE_INTERMEDIATE_IMAGES #define TEXTURE_QUANTIZATION 64 #define TEXTURE_QUANTIZATION 8 #define SQR(x) ((x)*(x)) #define SKIP GetRandomUniform(0.0, 1.0) //'multiple' should be ideally 10^desired_decimal_accuracy int inline RoundTo(const float val, const float multiple=1000.f) { Loading Loading @@ -1509,16 +1511,17 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) i3d::Image3d<float> perlinInner,perlinOutside; perlinInner.CopyMetaData(mask); // DoPerlin3D(perlinInner,5.0,0.8*1.5,0.7*1.5,6); DoPerlin3D(perlinInner,1.0,0.8*1.3,0.7*1.5,6); DoPerlin3D(perlinInner,1.0,0.3,1.0,6); Stretch(perlinInner, 0.0f, 1.0f, 4.0f); #ifdef SAVE_INTERMEDIATE_IMAGES //perlinInner.SaveImage("2_PerlinAlone_Inner.ics"); perlinInner.SaveImage("2_PerlinAlone_Inner.ics"); #endif perlinOutside.CopyMetaData(mask); DoPerlin3D(perlinOutside,1.4,0.8*1.1,0.7*1.5,6); DoPerlin3D(perlinOutside,2.5,0.2,1.0,6); Stretch(perlinOutside, 0.0f, 1.0f, 2.0f); #ifdef SAVE_INTERMEDIATE_IMAGES //perlinOutside.SaveImage("2_PerlinAlone_Outside.ics"); perlinOutside.SaveImage("2_PerlinAlone_Outside.ics"); #endif i3d::Image3d<i3d::GRAY16> erroded; Loading @@ -1530,23 +1533,37 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) const float* pI=perlinInner.GetFirstVoxelAddr(); const float* pO=perlinOutside.GetFirstVoxelAddr(); const i3d::GRAY16* er=erroded.GetFirstVoxelAddr(); // intensity values const float innerBg = 0.0; const float innerPerlinStrength = 20.0f; const float coronaBg = 1.0f; const float coronaPerlinStrength = 330.0f; // distances (in microns) const float coronaWidth = 0.1f; const float interfaceCoronaInterior = 0.05f; while (p != pL) { //are we within the mask? if (*p > 0.f) { //close to the surface? if (*p < 0.2f || *er == 0) *p=1000.f + 5000.f*(*pO); //corona else if (*p < 0.4f) if (*p < coronaWidth || *er == 0) *p=coronaBg + coronaPerlinStrength*(*pO); // corona else if (*p < (coronaWidth + interfaceCoronaInterior)) { float factor = (*p - 0.2f)/(0.2f); *p=(300.f + 600.f*(*pI))*factor + (1000.f + 5000.f*(*pO))*(1.0f-factor); // linear interpolation factor (between corona and interior) float factor = (*p - coronaWidth)/(interfaceCoronaInterior); *p=(innerBg + innerPerlinStrength*(*pI))*factor + (coronaBg + coronaPerlinStrength*(*pO))*(1.0f-factor); } else *p=300.f + 600.f*(*pI); //inside *p=innerBg + innerPerlinStrength*(*pI); //inside if (*er == 0) *p=1500.f; //corona if (*er == 0) *p=coronaBg; //corona envelope (was 1500) if (*p < 0.f) *p=0.f; } Loading Loading @@ -1576,7 +1593,7 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) for (int z=0; z < (signed)dt.GetSizeZ(); ++z) for (int y=0; y < (signed)dt.GetSizeY(); ++y) for (int x=0; x < (signed)dt.GetSizeX(); ++x, ++p) for (int v=0; v < *p; v+=TEXTURE_QUANTIZATION) for (int v=0; v < floorf(*p); v+=TEXTURE_QUANTIZATION) { //convert px coords into um, use centres of voxels const float X=(float(x)+0.5f)/xRes + xOff; Loading @@ -1599,6 +1616,11 @@ void ActiveMesh::InitDots_body(const i3d::Image3d<i3d::GRAY16>& mask) void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsigned int idx) { // get the resolution of image i3d::Vector3d<float> res = mask.GetResolution().GetRes(); float max_res = std::max(res.x, std::max(res.y, res.z)); // ... pixels/micron const int density = 10; // ... how may dots should be pressed between two neighbouring pixel positions //syntactic short-cut to the proper filopodium geometry data mesh_t& filoMesh=Ftree[idx]; Loading @@ -1610,10 +1632,14 @@ void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsig const Vector3F& fP=filoMesh.fPoints[filoMesh.segFromPoint[i]]; const Vector3F& tP=filoMesh.fPoints[filoMesh.segToPoint[i]]; const float length=(tP-fP).Len(); //full segment has length = 0.005 const float length=(tP-fP).Len(); // segment length in microns // discrete stepping const int S = (int) ceil(length * max_res * density); /// OBSOLETE - with magic factor //stepping along the axis const int S=(int)ceil(5.f*length/0.005); //"fraction factor" // const int S=(int)ceil(5.f*length/0.005); //"fraction factor" for (int s=0; s < S; ++s) { Loading @@ -1631,8 +1657,15 @@ void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsig Vector3F p =fS*fP; p+=tS*tP; // OBSOLETE - magic factor //insert fl. dots float dotsCount=400000.f*r; // float dotsCount=400000.f*r; // the number of dots should correspond the width (radius) of filopodium // multiplied by given density. The density should be a large number as the // radius is typically very small const int dotDensity = 5; float dotsCount = dotDensity*r; // prevent data overflow (5 - multiplicity of addition) int upper_limit = std::numeric_limits<i3d::GRAY16>::max() / (5 * TEXTURE_QUANTIZATION); Loading @@ -1650,21 +1683,29 @@ void ActiveMesh::InitDots_filo(const i3d::Image3d<i3d::GRAY16>& mask,const unsig Mul(mainDirection, vector2, vector4); // make them as small as the size of the radius in the given position vector1 *= r / vector1.Len(); vector2 *= r / vector2.Len(); vector3 *= r / vector3.Len(); vector4 *= r / vector4.Len(); vector1 /= vector1.Len(); vector2 /= vector2.Len(); vector3 /= vector3.Len(); vector4 /= vector4.Len(); int radiusInPixels = (int) ceil(r*max_res); for (int q=0; q < qM; ++q) { dots_filo.push_back(p); //dots_filo.push_back(p+Vector3F(0.0f,0.0f,+100*r)); //dots_filo.push_back(p+Vector3F(0.0f,0.0f,-100*r)); dots_filo.push_back(p+vector1); dots_filo.push_back(p+vector2); dots_filo.push_back(p+vector3); dots_filo.push_back(p+vector4); // The following cycle guarantees, that the dots will fill the filopodium // smoothly - from the center to the outer envelope. for (int step=0; step<=radiusInPixels; step++) { // how much the given vector should enlarge float scale = (r*(step+1.0f))/(radiusInPixels+1.0f); dots_filo.push_back(p+scale*vector1); dots_filo.push_back(p+scale*vector2); dots_filo.push_back(p+scale*vector3); dots_filo.push_back(p+scale*vector4); } } } } Loading Loading @@ -1868,10 +1909,6 @@ void PopulateCube(i3d::Image3d<i3d::GRAY16>& texture, { const int X=int(x-0.5f+float(ix)/float(xn)); ++T[X]; //DAVID: tady nepricitat +1, ale +GetRandomGauss(40.f,40.f/2.5f) //DAVID: ( za predpokladu, ze GetRandomGauss(mean,variance) ) //DAVID: variance nastavena zamerne s malym prekryvem //DAVID: pozor na pretekani intervalu GRAY16 //std::cout << "populating at [" << X << "," << Y << "," << Z << "]\n"; } Loading Loading @@ -1996,9 +2033,11 @@ void ActiveMesh::PhaseII(const i3d::Image3d<i3d::GRAY16>& texture, for (int y=0; y < (signed)blurred_texture.GetSizeY(); ++y) for (int x=0; x < (signed)blurred_texture.GetSizeX(); ++x, ++p) { // background signal: // max distance float maxDist = SQR((float)xC) + SQR((float)yC); // background signal (inverted parabola) float distSq = -(SQR((float)(x-xC)) + SQR((float)(y-yC)))/24200.f + 1.f; -(SQR((float)(x-xC)) + SQR((float)(y-yC)))/maxDist + 1.f; *p *= distSq; } #ifdef SAVE_INTERMEDIATE_IMAGES Loading @@ -2009,33 +2048,74 @@ void ActiveMesh::PhaseII(const i3d::Image3d<i3d::GRAY16>& texture, void ActiveMesh::PhaseIII(i3d::Image3d<float>& blurred, i3d::Image3d<i3d::GRAY16>& texture) { // NONSPECIFIC BACKGROUND i3d::Image3d<float> bgImg; bgImg.CopyMetaData(blurred); DoPerlin3D(bgImg,10.0,7.0,1.0,10); // very smooth a wide coherent noise // reset the maximum and minimin intesity levels of the background // to the expected values const float oldMaxI = bgImg.GetVoxelData().max(); const float oldMinI = bgImg.GetVoxelData().min(); const float newMaxI = 2.2f; const float newMinI = 2.0f; const float scale = (newMaxI-newMinI)/(oldMaxI-oldMinI); for (size_t i=0; i<bgImg.GetImageSize(); i++) { float value = bgImg.GetVoxel(i); value = scale*(value - oldMinI) + newMinI; bgImg.SetVoxel(i, value); } // given gain of EMCCD camera const int EMCCDgain = 1000; float* p=blurred.GetFirstVoxelAddr(); for (size_t i=0; i<blurred.GetImageSize(); i++, p++) { // shift the signal (simulates non-ideal black background) // ?reflection of medium? *p+=10.0f; *p+=bgImg.GetVoxel(i); // ENF ... Excess Noise Factor (stochasticity of EMCCD gain) // source of information: // https://www.qimaging.com/resources/pdfs/emccd_technote.pdf const float ENF = GetRandomUniform(1.0f, 1.4f); // PHOTON NOISE // uncertainty in the number of incoming photons // from statistics: shot noise = sqrt(signal) // from statistics: shot noise mean = sqrt(signal) const float noiseMean = sqrtf(*p); // for Poisson distribution E(X) = D(X) const float noiseVar = noiseMean; // SKIP avoid strong discretization of intenzity histogram due // to the Poisson probabilty function *p += ENF * ((float)GetRandomPoisson(noiseMean) - noiseMean + SKIP); *p+=40.f*((float)GetRandomPoisson(noiseMean) - noiseVar); //DAVID: tady odstranit 40.0f*, cili uz nenasobit //DAVID: bude asi nutne preladit vsechny Bulharske konstanty // EMCCD GAIN // amplification of signal (and inevitably also the noise) *p *= EMCCDgain; // DARK CURRENT // constants are parameters of Andor iXon camera provided from vendor: *p+=(float)GetRandomPoisson(0.06f); *p += ENF*EMCCDgain*(float)GetRandomPoisson(0.06f); // BASELINE (camera electron level) *p += 400.0f; // READOUT NOISE // variance up to 25.f (old camera on ILBIT) // variance about 1.f (for the new camera on ILBIT) *p+=GetRandomGauss(450.f,10.f); *p+=GetRandomGauss(0.0f,1.0f); // ADC (analogue-digital converter) // ADCgain ... how many electrons correcpond one intensity value // ADCoffset ... how much intensity levels are globally added to each pixel const float ADCgain = 28.0f; *p/=ADCgain; const float ADCoffset = 400.0f; *p+=ADCoffset; } #ifdef SAVE_INTERMEDIATE_IMAGES blurred.SaveImage("6_texture_finalized.ics"); Loading
src/TriangleMesh.h +2 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ class ActiveMesh void PopulateSurfTriangles_Ftree(const unsigned int idx,const bool enforce=false); ///renders filopodium first aside, then overlays the given mask void RenderMask_filo(i3d::Image3d<i3d::GRAY16>& mask,const unsigned int idx,const bool showTriangles=false); void RenderMask_filo(i3d::Image3d<i3d::GRAY16>& mask,const unsigned int idx, const unsigned short color=100,const bool showTriangles=false); /// render directly into mask using volumetric mesh void RenderMask_bodyVol(i3d::Image3d<i3d::GRAY16>& mask,const bool showTriangles=false); Loading
src/main_Generator.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ int main(int argc,char **argv) //translating all mesh points, to assure the meshes appear within //the produced images mesh.meshShift=minBB -Vector3F(1.0f); mesh.meshPlaygroundSize=(maxBB-minBB) +Vector3F(2.0f); mesh.meshPlaygroundSize=(maxBB-minBB) +Vector3F(5.0f); //NB: We also introduce 1um thick border around the mesh std::cout << "corners of a detected bounding box (with 1um thick border):\n"; std::cout << "[" << minBB.x << "," << minBB.y << "," << minBB.z << "] <-> [" Loading