Hi everyone,
I'm searching a way to convert a class (developed by our laboratory) to
ParaView plugin.
So, they have the vtkOtsuSphereSource.cxx and vtkOtsuSphereSource.h file as
in the attachments.
With this class, they will be able to calculate the optimal threshold of an
vtkImageData. The return value is this optimal threshold.
I have some questions to ask you about how to convert this class so it can
be used as ParaView plugin.
- What does it means "vtkStandardNewMacro(vtkOtsuSphereSource)" and does it
mandatory?
- Error when compiling vtkOtsuSphereSourceClientServer.cxx:13:10: error:
‘New’ is not a member of ‘vtkOtsuSphereSource’, so, it's because I don't have
static vtkOtsuSphereSource* New(); in the .h file. So I want to ask : what is
this?
- When I added this static vtkOtsuSphereSource* New(); in the .h file.
another compiling error :
/vtkOtsuSphereSource/bin/vtkOtsuSphereSourceClientServer.cxx:13:35: error:
cannot convert ‘vtkOtsuSphereSource*’ to ‘vtkObjectBase*’ in return so my class
is not a vtkObjectBase, but how can we go through this error?
The following lines indicate the compiling error with static
vtkOtsuSphereSource* New(); in .h file
/home/thtran/ParaViewPlugins/vtkOtsuSphereSource/bin/vtkOtsuSphereSourceClientServer.cxx:
In function ‘int vtkOtsuSphereSourceCommand(vtkClientServerInterpreter*,
vtkObjectBase*, const char*, const vtkClientServerStream&,
vtkClientServerStream&)’:
/home/thtran/ParaViewPlugins/vtkOtsuSphereSource/bin/vtkOtsuSphereSourceClientServer.cxx:19:29:
error: ‘SafeDownCast’ is not a member of ‘vtkOtsuSphereSource’
make[2]: ***
[CMakeFiles/MyOtsuSphereSource.dir/vtkOtsuSphereSourceClientServer.o] Error 1
make[1]: *** [CMakeFiles/MyOtsuSphereSource.dir/all] Error 2
Thank you very much in advance
#ifndef __VTK__VTK__OTSU__SPHERE__SOURCE__H__
#define __VTK__VTK__OTSU__SPHERE__SOURCE__H__
#include "vtkImageData.h"
class vtkOtsuSphereSource
{
public:
vtkOtsuSphereSource();
//static vtkOtsuSphereSource* New();
virtual ~vtkOtsuSphereSource();
double calculateOptimalThreshold(vtkImageData *voi);
vtkImageData* getImageForSegmentation();
private:
int* H;
double* SI;
double* P;
vtkImageData *volume;
vtkImageData *region;
vtkImageData *result;
};
#endif // __VTK__OTSU__SPHERE__SOURCE__H__
#include "vtkOtsuSphereSource.h"
//#include "vtkObjectFactory.h"
//vtkStandardNewMacro(vtkOtsuSphereSource);
//----------------------------------------------------------------------------
vtkOtsuSphereSource::vtkOtsuSphereSource(){
volume = NULL;
region = NULL;
result = NULL;
P = NULL;
}
//----------------------------------------------------------------------------
vtkOtsuSphereSource::~vtkOtsuSphereSource(){
}
//----------------------------------------------------------------------------
// Calculate Optimal Thershold with
// parameter in : vtkImageData
// parameter out : OptimalThreshold
double vtkOtsuSphereSource::calculateOptimalThreshold(vtkImageData* voi){
int extent[6];
double centro[3];
int static TAM = 2000;
this->volume = voi; //VOI
this->region = region; //JF
this->volume->GetExtent(extent);
centro[0] = (extent[0] + extent[1]) / 2;
centro[1] = (extent[2] + extent[3]) / 2;
centro[2] = (extent[4] + extent[5]) / 2;
double radio = (extent[1] - extent[0]) /(double)2.0;
result = vtkImageData::New();
result->DeepCopy(volume);
double valorEnRegion = 0.0;
double valor = 0.0;
int index = 0;
int T = 0;
int max=0;
int voxelCount = 0;
//1. Inicializacion
this->H = new int[TAM];
this->P = new double[TAM];
this->SI = new double[TAM];
for (index = 0; index <TAM; index++){
this->H[index] = 0;
this->P[index] = 0.0; //probabilidad acumulada
this->SI[index] = 0.0;
}
//2. Calcular el Histograma
double *ptr;
int i, j, k;
for(i=extent[0];i<=extent[1];i++){
for(j=extent[2];j<=extent[3];j++){
for(k=extent[4];k<=extent[5];k++){
ptr = (double *)this->result->GetScalarPointer(i,j,k);
// verificar si esta dentro de la esfera
if( ((i-centro[0])*(i-centro[0]) +
(j-centro[1])*(j-centro[1]) +
(k-centro[2])*(k-centro[2])) <= (radio*radio)){
valor = this->volume->GetScalarComponentAsDouble(i,j,k,0);
if (valor > max){
max = (int)valor;
}
index = (int)valor;
this->H[index]++;
voxelCount++;
}
else {
*ptr=0.0;
}
}
}
}
//3. Normalizacion de la funcion P
for(index=0;index<=max;index++){
this->P[index] = (double)this->H[index] / (double)voxelCount;
}
//4. Recorrer los diferentes niveles de intensidad
for(T=0;T<=max;T++){
//4.1 Calcular las probabilidades acumuladas de las clases A y B
double Q1 = 0.0;
double Q2 = 0.0;
for(index=0;index<=max;index++){
if (index < T){
Q1 = Q1 + this->P[index];
}
else{
Q2 = Q2 + this->P[index];
}
}
//4.2 Calcular las medias de las clases A y B
double U1 = 0.0;
double U2 = 0.0;
for (index=0;index<=max;index++){
if (index < T){
U1 = U1 + ((double)(index * this->P[index])/(double)Q1);
}
else{
U2 = U2 + ((double)(index * this->P[index])/(double)Q2);
}
}
//4.3 Calcular las varianzas individuales
double S1 = 0.0;
double S2 = 0.0;
for (index=0;index<=max;index++){
if (index < T){
S1 = S1 + ((index - U1)*(index - U1)*(this->P[index]/(double)Q1));
}
else{
S2 = S2 + ((index - U2)*(index - U2)*(this->P[index]/(double)Q2));
}
}
//4.4 Calcular SI: La varianza intraclases y seleccionar el valor minimo
this->SI[T] = Q1*S1 + Q2*S2;
}
int optimalThreshold = 0;
double optimalCriteria = VTK_LARGE_FLOAT;
for (index=0;index<=max;index++){
if (SI[index] < optimalCriteria){
optimalCriteria = SI[index];
optimalThreshold = index;
}
}
return optimalThreshold;
}
//----------------------------------------------------------------------------
// Getter of vtkOtsuSphereSource for vtkImageData (in input)
vtkImageData* vtkOtsuSphereSource::getImageForSegmentation(){
return this->result;
}
_______________________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
Please keep messages on-topic and check the ParaView Wiki at:
http://paraview.org/Wiki/ParaView
Follow this link to subscribe/unsubscribe:
http://www.paraview.org/mailman/listinfo/paraview