Exemple #1
0
bool fillRegularVolumeInfo( VolumeInformation& info )
{
    info.worldSpacePerVoxel = 1.0f / float( info.voxels.find_max( ));
    info.worldSize = Vector3f( info.voxels[0], info.voxels[1],
                               info.voxels[2] ) * info.worldSpacePerVoxel;

    // Create the rootNode of the LOD hierarchy
    const Vector3ui blockSize = info.maximumBlockSize - info.overlap * 2;
    const Vector3ui numBlocks(
                std::ceil( float( info.voxels.x( )) / blockSize.x( )),
                std::ceil( float( info.voxels.y( )) / blockSize.y( )),
                std::ceil( float( info.voxels.z( )) / blockSize.z( ))
                );
    const Vector3ui lodLevels(
                std::ceil( std::log2( numBlocks.x( ))),
                std::ceil( std::log2( numBlocks.y( ))),
                std::ceil( std::log2( numBlocks.z( )))
                );
    const uint32_t depth = lodLevels.find_min();
    const Vector3ui rootNodeBlocksCount(
                std::ceil( float( info.voxels.x() >> depth ) / blockSize.x( )),
                std::ceil( float( info.voxels.y() >> depth ) / blockSize.y( )),
                std::ceil( float( info.voxels.z() >> depth ) / blockSize.z( ))
                );
    info.rootNode = RootNode( depth + 1, rootNodeBlocksCount );
    return true;
}
void SeededRegionGrowing::executeOnHost(T* input, Image::pointer output) {
    ImageAccess::pointer outputAccess = output->getImageAccess(ACCESS_READ_WRITE);
    uchar* outputData = (uchar*)outputAccess->get();
    // initialize output to all zero
    memset(outputData, 0, output->getWidth()*output->getHeight()*output->getDepth());
    std::stack<Vector3ui> queue;

    // Add seeds to queue
    for(int i = 0; i < mSeedPoints.size(); i++) {
        Vector3ui pos = mSeedPoints[i];

        // Check if seed point is in bounds
        if(pos.x() < 0 || pos.y() < 0 || pos.z() < 0 ||
            pos.x() >= output->getWidth() || pos.y() >= output->getHeight() || pos.z() >= output->getDepth())
            throw Exception("One of the seed points given to SeededRegionGrowing was out of bounds.");

        queue.push(pos);
    }

    // Process queue
    while(!queue.empty()) {
        Vector3ui pos = queue.top();
        queue.pop();

        // Add neighbors to queue
        for(int a = -1; a < 2; a++) {
        for(int b = -1; b < 2; b++) {
        for(int c = -1; c < 2; c++) {
            if(abs(a)+abs(b)+abs(c) != 1) // connectivity
                continue;
            Vector3ui neighbor(pos.x()+a,pos.y()+b,pos.z()+c);
            // Check for out of bounds
            if(neighbor.x() < 0 || neighbor.y() < 0 || neighbor.z() < 0 ||
                neighbor.x() >= output->getWidth() || neighbor.y() >= output->getHeight() || neighbor.z() >= output->getDepth())
                continue;

            // Check that voxel is not already segmented
            if(outputData[neighbor.x()+neighbor.y()*output->getWidth()+neighbor.z()*output->getWidth()*output->getHeight()] == 1)
                continue;

            // Check condition
            T value = input[neighbor.x()+neighbor.y()*output->getWidth()+neighbor.z()*output->getWidth()*output->getHeight()];
            if(value >= mMinimumIntensity && value <= mMaximumIntensity) {
                // add it to segmentation
                outputData[neighbor.x()+neighbor.y()*output->getWidth()+neighbor.z()*output->getWidth()*output->getHeight()] = 1;

                // Add to queue
                queue.push(neighbor);
            }
        }}}
    }
}
Exemple #3
0
/*===========================================================================*/
void ExtractEdges::calculate_connections( const kvs::StructuredVolumeObject* volume )
{
    const size_t line_size = volume->numberOfNodesPerLine();
    const size_t slice_size = volume->numberOfNodesPerSlice();
    const Vector3ui resolution( volume->resolution() );
    const size_t nedges =
        3 * ( resolution.x() - 1 ) * ( resolution.y() - 1 ) * ( resolution.z() - 1 ) +
        2 * ( resolution.x() - 1 ) * ( resolution.y() - 1 ) +
        2 * ( resolution.y() - 1 ) * ( resolution.z() - 1 ) +
        2 * ( resolution.z() - 1 ) * ( resolution.x() - 1 ) +
        resolution.x() - 1 + resolution.y() - 1 + resolution.z() - 1;

    kvs::ValueArray<kvs::UInt32> connections( 2 * nedges );
    kvs::UInt32* connection = connections.data();

    kvs::UInt32 volume_vertex = 0;
    kvs::UInt32 connection_index = 0;
    for ( size_t z = 0; z < resolution.z(); ++z )
    {
        for ( size_t y = 0; y < resolution.y(); ++y )
        {
            for ( size_t x = 0; x < resolution.x(); ++x )
            {
                if ( x != resolution.x() - 1 )
                {
                    connection[ connection_index++ ] = volume_vertex;
                    connection[ connection_index++ ] = volume_vertex + 1;
                }

                if ( y != resolution.y() - 1 )
                {
                    connection[ connection_index++ ] = volume_vertex;
                    connection[ connection_index++ ] = volume_vertex + line_size;
                }

                if ( z != resolution.z() - 1 )
                {
                    connection[ connection_index++ ] = volume_vertex;
                    connection[ connection_index++ ] = volume_vertex + slice_size;
                }

                ++volume_vertex;
            }
        }
    }

    SuperClass::setConnections( connections );
}
Exemple #4
0
void setScalarAsFloat(T* data, VectorXi position, Image::pointer image, float value, uchar channel) {

    Vector3ui size = image->getSize();
    if(position.x() < 0 || position.y() < 0 || position.z() < 0 ||
            position.x() > size.x()-1 || position.y() > size.y()-1 || position.z() > size.z()-1 || channel >= image->getNrOfComponents())
        throw OutOfBoundsException();

    uint address = (position.x() + position.y()*size.x() + position.z()*size.x()*size.y())*image->getNrOfComponents() + channel;
    if(image->getDataType() == TYPE_SNORM_INT16) {
        data[address] = value * 32767.0f;;
    } else if(image->getDataType() == TYPE_UNORM_INT16) {
        data[address] = value * 65535.0f;;
    } else {
        data[address] = value;
    }
}
Exemple #5
0
void Dilation::execute() {
    Image::pointer input = getInputData<Image>();
    if(input->getDataType() != TYPE_UINT8) {
        throw Exception("Data type of image given to Dilation must be UINT8");
    }

    Image::pointer output = getOutputData<Image>();
    output->createFromImage(input);
    SceneGraph::setParentNode(output, input);
    output->fill(0);

    OpenCLDevice::pointer device = std::dynamic_pointer_cast<OpenCLDevice>(getMainDevice());
    cl::CommandQueue queue = device->getCommandQueue();
    cl::Program program = getOpenCLProgram(device);
    cl::Kernel dilateKernel(program, "dilate");

    Vector3ui size = input->getSize();

    OpenCLImageAccess::pointer access = input->getOpenCLImageAccess(ACCESS_READ, device);
    dilateKernel.setArg(0, *access->get3DImage());
    dilateKernel.setArg(2, mSize/2);

    if(!device->isWritingTo3DTexturesSupported()) {
        OpenCLBufferAccess::pointer access2 = output->getOpenCLBufferAccess(ACCESS_READ_WRITE, device);
        dilateKernel.setArg(1, *access2->get());

        queue.enqueueNDRangeKernel(
            dilateKernel,
            cl::NullRange,
            cl::NDRange(size.x(), size.y(), size.z()),
            cl::NullRange
        );
    } else {
        OpenCLImageAccess::pointer access2 = output->getOpenCLImageAccess(ACCESS_READ_WRITE, device);
        dilateKernel.setArg(1, *access2->get3DImage());

        queue.enqueueNDRangeKernel(
            dilateKernel,
            cl::NullRange,
            cl::NDRange(size.x(), size.y(), size.z()),
            cl::NullRange
        );
    }

}
void VTKMeshFileExporter::execute() {
    if(mFilename == "")
        throw Exception("No filename given to the VTKMeshFileExporter");

    Mesh::pointer surface = getStaticInputData<Mesh>();

    // Get transformation
    AffineTransformation::pointer transform = SceneGraph::getAffineTransformationFromData(surface);

    std::ofstream file(mFilename.c_str());

    if(!file.is_open())
        throw Exception("Unable to open the file " + mFilename);

    // Write header
    file << "# vtk DataFile Version 3.0\n"
         "vtk output\n"
         "ASCII\n"
         "DATASET POLYDATA\n";

    // Write vertices
    MeshAccess::pointer access = surface->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> vertices = access->getVertices();
    file << "POINTS " << vertices.size() << " float\n";
    for(int i = 0; i < vertices.size(); i++) {
        MeshVertex vertex = vertices[i];
        vertex.position = (transform->matrix()*vertex.position.homogeneous()).head(3);
        file << vertex.position.x() << " " << vertex.position.y() << " " << vertex.position.z() << "\n";
    }

    // Write triangles
    std::vector<Vector3ui> triangles = access->getTriangles();
    file << "POLYGONS " << surface->getNrOfTriangles() << " " << surface->getNrOfTriangles()*4 << "\n";
    for(int i = 0; i < triangles.size(); i++) {
        Vector3ui triangle = triangles[i];
        file << "3 " << triangle.x() << " " << triangle.y() << " " << triangle.z() << "\n";
    }

    // Write normals
    file << "POINT_DATA " << vertices.size() << "\n";
    file << "NORMALS Normals float\n";
    for(int i = 0; i < vertices.size(); i++) {
        MeshVertex vertex = vertices[i];
        // Transform it
        vertex.normal = transform->linear()*vertex.normal;
        // Normalize it
        float length = vertex.normal.norm();
        if(length == 0) { // prevent NaN situations
            file << "0 1 0\n";
        } else {
            file << (vertex.normal.x()/length) << " " << (vertex.normal.y()/length) << " " << (vertex.normal.z()/length) << "\n";
        }
    }

    file.close();
}
bool checkCompatibility( const Vector3ui& volumeDim,
                         const Vector3ui& blockSize )
{
    if( volumeDim.x() % blockSize.x() )
        return false;
    if( volumeDim.y() % blockSize.y() )
        return false;
    if( volumeDim.z() % blockSize.z() )
        return false;

    if( !isPowerOfTwo( volumeDim.x() / blockSize.x() ) )
        return false;
    if( !isPowerOfTwo( volumeDim.y() / blockSize.y() ) )
        return false;
    if( !isPowerOfTwo( volumeDim.z() / blockSize.z() ) )
        return false;

    return true;
}
Exemple #8
0
float getScalarAsFloat(T* data, VectorXi position, Image::pointer image, uchar channel) {

    Vector3ui size = image->getSize();
    if(position.x() < 0 || position.y() < 0 || position.z() < 0 ||
            position.x() > size.x()-1 || position.y() > size.y()-1 || position.z() > size.z()-1 || channel >= image->getNrOfComponents())
        throw OutOfBoundsException();

    T value = data[(position.x() + position.y()*size.x() + position.z()*size.x()*size.y())*image->getNrOfComponents() + channel];
    float floatValue;
    if(image->getDataType() == TYPE_SNORM_INT16) {
        floatValue = std::max(-1.0f, (float)value / 32767.0f);
    } else if(image->getDataType() == TYPE_UNORM_INT16) {
        floatValue = (float)value / 65535.0f;
    } else {
        floatValue = value;
    }

    return floatValue;
}
Exemple #9
0
cl::size_t<3> createRegion(Vector3ui size) {
    return createRegion(size.x(), size.y(), size.z());
}
void SeededRegionGrowing::execute() {
    if(mSeedPoints.size() == 0)
        throw Exception("No seed points supplied to SeededRegionGrowing");

    Image::pointer input = getStaticInputData<Image>();
    if(input->getNrOfComponents() != 1)
        throw Exception("Seeded region growing currently doesn't support images with several components.");

    Segmentation::pointer output = getStaticOutputData<Segmentation>();

    // Initialize output image
    output->createFromImage(input, getMainDevice());

    if(getMainDevice()->isHost()) {
        ImageAccess::pointer inputAccess = input->getImageAccess(ACCESS_READ);
        void* inputData = inputAccess->get();
        switch(input->getDataType()) {
            fastSwitchTypeMacro(executeOnHost<FAST_TYPE>((FAST_TYPE*)inputData, output));
        }
    } else {
        OpenCLDevice::pointer device = getMainDevice();

        recompileOpenCLCode(input);

        ImageAccess::pointer access = output->getImageAccess(ACCESS_READ_WRITE);
        uchar* outputData = (uchar*)access->get();
        // Initialize to all 0s
        memset(outputData,0,sizeof(uchar)*output->getWidth()*output->getHeight()*output->getDepth());

        // Add sedd points
        for(int i = 0; i < mSeedPoints.size(); i++) {
            Vector3ui pos = mSeedPoints[i];

            // Check if seed point is in bounds
            if(pos.x() < 0 || pos.y() < 0 || pos.z() < 0 ||
                pos.x() >= output->getWidth() || pos.y() >= output->getHeight() || pos.z() >= output->getDepth())
                throw Exception("One of the seed points given to SeededRegionGrowing was out of bounds.");

            outputData[pos.x() + pos.y()*output->getWidth() + pos.z()*output->getWidth()*output->getHeight()] = 2;
        }
        access->release();

        cl::NDRange globalSize;
        if(output->getDimensions() == 2) {
            globalSize = cl::NDRange(input->getWidth(),input->getHeight());
            OpenCLImageAccess2D::pointer inputAccess = input->getOpenCLImageAccess2D(ACCESS_READ, device);
            mKernel.setArg(0, *inputAccess->get());
        } else {
            globalSize = cl::NDRange(input->getWidth(),input->getHeight(), input->getDepth());
            OpenCLImageAccess3D::pointer inputAccess = input->getOpenCLImageAccess3D(ACCESS_READ, device);
            mKernel.setArg(0, *inputAccess->get());
        }

        OpenCLBufferAccess::pointer outputAccess = output->getOpenCLBufferAccess(ACCESS_READ_WRITE, device);
        cl::Buffer stopGrowingBuffer = cl::Buffer(
                device->getContext(),
                CL_MEM_READ_WRITE,
                sizeof(char));
        cl::CommandQueue queue = device->getCommandQueue();
        mKernel.setArg(1, *outputAccess->get());
        mKernel.setArg(2, stopGrowingBuffer);
        mKernel.setArg(3, mMinimumIntensity);
        mKernel.setArg(4, mMaximumIntensity);

        bool stopGrowing = false;
        char stopGrowingInit = 1;
        char * stopGrowingResult = new char;
        int iterations = 0;
        do {
            iterations++;
            queue.enqueueWriteBuffer(stopGrowingBuffer, CL_TRUE, 0, sizeof(char), &stopGrowingInit);

            queue.enqueueNDRangeKernel(
                    mKernel,
                    cl::NullRange,
                    globalSize,
                    cl::NullRange
            );

            queue.enqueueReadBuffer(stopGrowingBuffer, CL_TRUE, 0, sizeof(char), stopGrowingResult);
            if(*stopGrowingResult == 1)
                stopGrowing = true;
        } while(!stopGrowing);
    }

}