Esempio n. 1
0
void MetaImageImporter::execute() {
    if(mFilename == "")
        throw Exception("Filename was not set in MetaImageImporter");

    // Open and parse mhd file
    std::fstream mhdFile;
    mhdFile.open(mFilename.c_str(), std::fstream::in);
    if(!mhdFile.is_open())
        throw FileNotFoundException(mFilename);
    std::string line;
    std::string rawFilename;
    bool sizeFound = false,
         rawFilenameFound = false,
         typeFound = false,
         dimensionsFound = false;
    std::string typeName;

    // Find NDims first
    bool imageIs3D = false;
    do {
        std::getline(mhdFile, line);
        if(line.substr(0, 5) == "NDims") {
            if(line.substr(5+3, 1) == "3") {
                imageIs3D = true;
            } else if(line.substr(5+3, 1) == "2") {
                imageIs3D = false;
            }
            dimensionsFound = true;
        }
    } while(!mhdFile.eof() && !dimensionsFound);

    if(!dimensionsFound)
        throw Exception("NDims not found in metaimage file.");

    // Reset and start reading file from beginning
    mhdFile.seekg(0);

    unsigned int width, height, depth = 1;
    unsigned int nrOfComponents = 1;
    Image::pointer output = getOutputData<Image>(0);

    Vector3f spacing(1,1,1), offset(0,0,0), centerOfRotation(0,0,0);
    Matrix3f transformMatrix = Matrix3f::Identity();
    bool isCompressed = false;
    std::size_t compressedDataSize = 0;

    do{
        std::getline(mhdFile, line);
        boost::trim(line);
        if(line.size() == 0) // line is empty
            continue;
        int firstSpace = line.find(" ");
        std::string key = line.substr(0, firstSpace);
        boost::trim(key);
        int equalSignPos = line.find("=");
        std::string value = line.substr(equalSignPos+1);
        boost::trim(value);
        if(key == "DimSize") {
            std::vector<std::string> values;
            boost::split(values, value, boost::is_any_of(" "));
            // Remove any empty values:
            values.erase(std::remove(values.begin(), values.end(), ""), values.end());

            if(imageIs3D) {
                if(values.size() != 3)
                    throw Exception("DimSize in MetaImage file did not contain 3 numbers");
                depth = boost::lexical_cast<int>(values[2]);
            } else {
                if(values.size() != 2)
                    throw Exception("DimSize in MetaImage file did not contain 2 numbers");
            }
            width = boost::lexical_cast<int>(values[0]);
            height = boost::lexical_cast<int>(values[1]);
            sizeFound = true;
        } else if(key == "CompressedData" && value == "True") {
            isCompressed = true;
        } else if(key == "CompressedDataSize") {
            compressedDataSize = boost::lexical_cast<int>(value);
        } else if(key == "ElementDataFile") {
            rawFilename = value;
            rawFilenameFound = true;

            // Remove any trailing spaces
            int pos = rawFilename.find(" ");
            if(pos > 0)
            rawFilename = rawFilename.substr(0,pos);

            // Get path name
            pos = mFilename.rfind('/');
            if(pos > 0)
                rawFilename = mFilename.substr(0,pos+1) + rawFilename;
        } else if(key == "ElementType") {
            typeFound = true;
            typeName = value;

            // Remove any trailing spaces
            int pos = typeName.find(" ");
            if(pos > 0)
            typeName = typeName.substr(0,pos);

            if(typeName == "MET_SHORT") {
            } else if(typeName == "MET_USHORT") {
            } else if(typeName == "MET_CHAR") {
            } else if(typeName == "MET_UCHAR") {
            } else if(typeName == "MET_INT") {
            } else if(typeName == "MET_UINT") {
            } else if(typeName == "MET_FLOAT") {
            } else {
                throw Exception("Trying to read volume of unsupported data type", __LINE__, __FILE__);
            }
        } else if(key == "ElementNumberOfChannels") {
            nrOfComponents = boost::lexical_cast<int>(value.c_str());
            if(nrOfComponents <= 0)
                throw Exception("Error in reading the number of components in the MetaImageImporter");
        } else if(key == "ElementSpacing") {
            std::vector<std::string> values;
            boost::split(values, value, boost::is_any_of(" "));
            // Remove any empty values:
            values.erase(std::remove(values.begin(), values.end(), ""), values.end());
            if(imageIs3D) {
                if(values.size() != 3)
                    throw Exception("ElementSpacing in MetaImage file did not contain 3 numbers");
                spacing[0] = boost::lexical_cast<float>(values[0]);
                spacing[1] = boost::lexical_cast<float>(values[1]);
                spacing[2] = boost::lexical_cast<float>(values[2]);
            } else {
                if(values.size() != 2 && values.size() != 3)
                    throw Exception("ElementSpacing in MetaImage file did not contain 2 or 3 numbers");

                spacing[0] = boost::lexical_cast<float>(values[0]);
                spacing[1] = boost::lexical_cast<float>(values[1]);
                if(values.size() == 2) {
                    spacing[2] = 1;
                } else {
                    spacing[2] = boost::lexical_cast<float>(values[2]);
                }
            }


        } else if(key == "CenterOfRotation") {
            //reportInfo() << "WARNING: CenterOfRotation in Metaimage file ignored" << Reporter::end;
            std::vector<std::string> values;
            boost::split(values, value, boost::is_any_of(" "));
            // Remove any empty values:
            values.erase(std::remove(values.begin(), values.end(), ""), values.end());
            if(imageIs3D) {
                if(values.size() != 3)
                    throw Exception("CenterOfRotation in MetaImage file did not contain 3 numbers");
                centerOfRotation[0] = boost::lexical_cast<float>(values[0]);
                centerOfRotation[1] = boost::lexical_cast<float>(values[1]);
                centerOfRotation[2] = boost::lexical_cast<float>(values[2]);
            } else {
                if(values.size() != 2 && values.size() != 3)
                    throw Exception("CenterOfRotation in MetaImage file did not contain 2 or 3 numbers");

                centerOfRotation[0] = boost::lexical_cast<float>(values[0]);
                centerOfRotation[1] = boost::lexical_cast<float>(values[1]);
                if(values.size() == 2) {
                    centerOfRotation[2] = 0;
                } else {
                    centerOfRotation[2] = boost::lexical_cast<float>(values[2]);
                }
            }
        } else if(key == "Offset" || key == "Origin" || key == "Position") {
            std::vector<std::string> values;
            boost::split(values, value, boost::is_any_of(" "));
            // Remove any empty values:
            values.erase(std::remove(values.begin(), values.end(), ""), values.end());
            if(values.size() != 3)
                throw Exception("Offset/Origin/Position in MetaImage file did not contain 3 numbers");

            offset[0] = boost::lexical_cast<float>(values[0].c_str());
            offset[1] = boost::lexical_cast<float>(values[1].c_str());
            offset[2] = boost::lexical_cast<float>(values[2].c_str());
        } else if(key == "TransformMatrix" || key == "Rotation" || key == "Orientation") {
            std::vector<std::string> values;
            boost::split(values, value, boost::is_any_of(" "));
            // Remove any empty values:
            values.erase(std::remove(values.begin(), values.end(), ""), values.end());
            if(values.size() != 9)
                throw Exception("Encountered a transform/orientation/rotation matrix with incorrect number of elements in the MetaImageImporter");

            for(unsigned int i = 0; i < 3; i++) {
            for(unsigned int j = 0; j < 3; j++) {
                transformMatrix(j,i) = boost::lexical_cast<float>(values[j+i*3].c_str());
            }}
        }

    } while(!mhdFile.eof());

    mhdFile.close();
    if(!sizeFound || !rawFilenameFound || !typeFound || !dimensionsFound)
        throw Exception("Error reading the mhd file", __LINE__, __FILE__);


    void * data;
    DataType type;
    if(typeName == "MET_SHORT") {
        type = TYPE_INT16;
        data = readRawData<short>(rawFilename, width, height, depth, nrOfComponents, isCompressed, compressedDataSize);
    } else if(typeName == "MET_USHORT") {
        type = TYPE_UINT16;
        data = readRawData<unsigned short>(rawFilename, width, height, depth, nrOfComponents, isCompressed, compressedDataSize);
    } else if(typeName == "MET_CHAR") {
        type = TYPE_INT8;
        data = readRawData<char>(rawFilename, width, height, depth, nrOfComponents, isCompressed, compressedDataSize);
    } else if(typeName == "MET_UCHAR") {
        type = TYPE_UINT8;
        data = readRawData<unsigned char>(rawFilename, width, height, depth, nrOfComponents, isCompressed, compressedDataSize);
    } else if(typeName == "MET_FLOAT") {
        type = TYPE_FLOAT;
        data = readRawData<float>(rawFilename, width, height, depth, nrOfComponents, isCompressed, compressedDataSize);
    }

    if(imageIs3D) {
        output->create(width,height,depth,type,nrOfComponents,getMainDevice(),data);
    } else {
        output->create(width,height,type,nrOfComponents,getMainDevice(),data);
    }

    output->setSpacing(spacing);

    // Create transformation
    AffineTransformation::pointer T = AffineTransformation::New();
    T->translation() = offset;
    T->linear() = transformMatrix;
    output->getSceneGraphNode()->setTransformation(T);

    // Clean up
    deleteArray(data, type);
}
Esempio n. 2
0
/*
void NoneLocalMeans::recompileOpenCLCode(Image::pointer input) {
	// Check if there is a need to recompile OpenCL code
	if (input->getDimensions() == mDimensionCLCodeCompiledFor &&
		input->getDataType() == mTypeCLCodeCompiledFor && !recompile)
		return;

	OpenCLDevice::pointer device = getMainDevice();
    recompile = false;
	std::string buildOptions = "";
	const bool writingTo3DTextures = device->getDevice().getInfo<CL_DEVICE_EXTENSIONS>().find("cl_khr_3d_image_writes") != std::string::npos;
	if (!writingTo3DTextures) {
		switch (mOutputType) {
		case TYPE_FLOAT:
			buildOptions += " -DTYPE=float";
			break;
		case TYPE_INT8:
			buildOptions += " -DTYPE=char";
			break;
		case TYPE_UINT8:
			buildOptions += " -DTYPE=uchar";
			break;
		case TYPE_INT16:
			buildOptions += " -DTYPE=short";
			break;
		case TYPE_UINT16:
			buildOptions += " -DTYPE=ushort";
			break;
		}
	}
    buildOptions += " -D WINDOW=";
    buildOptions += std::to_string((windowSize-1)/2);
	buildOptions += " -D GROUP=";
    buildOptions += std::to_string((groupSize-1)/2);
    
	std::string filename;
	//might have to seperate color vs gray here, for better runtime
	if (input->getDimensions() == 2) {
        if(k == 0){
            filename = "Algorithms/NoneLocalMeans/NoneLocalMeans2Dconstant.cl";
        }else if(k == 1){
            filename = "Algorithms/NoneLocalMeans/NoneLocalMeans2Dgaussian.cl";
        }else{
            filename = "Algorithms/NoneLocalMeans/NoneLocalMeans2Dconstant.cl";
        }
		//filename = "Algorithms/NoneLocalMeans/NoneLocalMeans2DgsPixelWise.cl";
		//filename = "Algorithms/NoneLocalMeans/NoneLocalMeans2Dgs.cl";
        //filename = "Algorithms/NoneLocalMeans/NoneLocalMeans2Dc.cl";
	}
	else {
		filename = "Algorithms/NoneLocalMeans/NoneLocalMeans3Dgs.cl";
	}
	int programNr = device->createProgramFromSource(std::string(FAST_SOURCE_DIR) + filename, buildOptions);
	mKernel = cl::Kernel(device->getProgram(programNr), "noneLocalMeans");
	mDimensionCLCodeCompiledFor = input->getDimensions();
	mTypeCLCodeCompiledFor = input->getDataType();
}*/
void NoneLocalMeans::execute() {
    Image::pointer input = getStaticInputData<Image>(0);
    Image::pointer output = getStaticOutputData<Image>(0);
    
    // Initialize output image
    ExecutionDevice::pointer device = getMainDevice();
    if(mOutputTypeSet) {
        output->create(input->getSize(), mOutputType, input->getNrOfComponents());
        output->setSpacing(input->getSpacing());
    } else {
        output->createFromImage(input);
    }
    mOutputType = output->getDataType();
    SceneGraph::setParentNode(output, input);
    
    
    if(device->isHost()) {
        switch(input->getDataType()) {
                fastSwitchTypeMacro(executeAlgorithmOnHost<FAST_TYPE>(input, output, groupSize, windowSize, denoiseStrength, sigma));
        }
    } else {
        OpenCLDevice::pointer clDevice = device;
        
        recompileOpenCLCode(input);
        
        cl::NDRange globalSize;
        
        OpenCLImageAccess::pointer inputAccess = input->getOpenCLImageAccess(ACCESS_READ, device);
        if(input->getDimensions() == 2) {
            OpenCLImageAccess::pointer outputAccess = output->getOpenCLImageAccess(ACCESS_READ_WRITE, device);
            mKernel.setArg(2, (denoiseStrength*denoiseStrength));
            mKernel.setArg(3, (sigma*sigma));
            globalSize = cl::NDRange(input->getWidth(),input->getHeight());
            mKernel.setArg(0, *inputAccess->get2DImage());
            mKernel.setArg(1, *outputAccess->get2DImage());
            clDevice->getCommandQueue().enqueueNDRangeKernel(
                    mKernel,
                    cl::NullRange,
                    globalSize,
                    cl::NullRange
            );
        } else {
            // Create an auxilliary image
            //Image::pointer output2 = Image::New();
            //output2->createFromImage(output);
            
            globalSize = cl::NDRange(input->getWidth(),input->getHeight(),input->getDepth());
            
            if(clDevice->isWritingTo3DTexturesSupported()) {
                mKernel.setArg(2, (denoiseStrength*denoiseStrength));
                mKernel.setArg(3, (sigma*sigma));
                OpenCLImageAccess::pointer outputAccess = output->getOpenCLImageAccess(ACCESS_READ_WRITE, device);
                //OpenCLImageAccess::pointer outputAccess2 = output2->getOpenCLImageAccess(ACCESS_READ_WRITE, device);
                
                //cl::Image3D* image2;
                cl::Image3D* image;
                image = outputAccess->get3DImage();
                //image2 = outputAccess->get3DImage();
                mKernel.setArg(0, *inputAccess->get3DImage());
                mKernel.setArg(1, *image);
                clDevice->getCommandQueue().enqueueNDRangeKernel(
                        mKernel,
                        cl::NullRange,
                        globalSize,
                        cl::NullRange
                );
            }else{
                mKernel.setArg(2, (denoiseStrength*denoiseStrength));
                mKernel.setArg(3, (sigma*sigma));
                OpenCLBufferAccess::pointer outputAccess = output->getOpenCLBufferAccess(ACCESS_READ_WRITE, device);
                mKernel.setArg(0, *inputAccess->get3DImage());
                mKernel.setArg(1, *outputAccess->get());
                clDevice->getCommandQueue().enqueueNDRangeKernel(
                        mKernel,
                        cl::NullRange,
                        globalSize,
                        cl::NullRange
                );
            }
            
            
        }
    }
}
Esempio n. 3
0
void ImageSlicer::orthogonalSlicing(Image::pointer input, Image::pointer output) {
    OpenCLDevice::pointer device = getMainDevice();

    // Determine slice nr and width and height
    unsigned int sliceNr;
    if(mOrthogonalSliceNr < 0) {
        switch(mOrthogonalSlicePlane) {
        case PLANE_X:
            sliceNr = input->getWidth()/2;
            break;
        case PLANE_Y:
            sliceNr = input->getHeight()/2;
            break;
        case PLANE_Z:
            sliceNr = input->getDepth()/2;
            break;
        }
    } else {
        // Check that mSliceNr is valid
        sliceNr = mOrthogonalSliceNr;
        switch(mOrthogonalSlicePlane) {
        case PLANE_X:
            if(sliceNr >= input->getWidth())
                sliceNr = input->getWidth()-1;
            break;
        case PLANE_Y:
            if(sliceNr >= input->getHeight())
                sliceNr = input->getHeight()-1;
            break;
        case PLANE_Z:
            if(sliceNr >= input->getDepth())
                sliceNr = input->getDepth()-1;
            break;
        }
    }
    unsigned int slicePlaneNr, width, height;
    Vector3f spacing(0,0,0);
    switch(mOrthogonalSlicePlane) {
        case PLANE_X:
            slicePlaneNr = 0;
            width = input->getHeight();
            height = input->getDepth();
            spacing.x() = input->getSpacing().y();
            spacing.y() = input->getSpacing().z();
            break;
        case PLANE_Y:
            slicePlaneNr = 1;
            width = input->getWidth();
            height = input->getDepth();
            spacing.x() = input->getSpacing().x();
            spacing.y() = input->getSpacing().z();
            break;
        case PLANE_Z:
            slicePlaneNr = 2;
            width = input->getWidth();
            height = input->getHeight();
            spacing.x() = input->getSpacing().x();
            spacing.y() = input->getSpacing().y();
            break;
    }

    output->create(width, height, input->getDataType(), input->getNrOfComponents());
    output->setSpacing(spacing);

    OpenCLImageAccess::pointer inputAccess = input->getOpenCLImageAccess(ACCESS_READ, device);
    OpenCLImageAccess::pointer outputAccess = output->getOpenCLImageAccess(ACCESS_READ_WRITE, device);

	cl::CommandQueue queue = device->getCommandQueue();
	cl::Program program = getOpenCLProgram(device);
	cl::Kernel kernel(program, "orthogonalSlicing");

    kernel.setArg(0, *inputAccess->get3DImage());
    kernel.setArg(1, *outputAccess->get2DImage());
    kernel.setArg(2, sliceNr);
    kernel.setArg(3, slicePlaneNr);
    queue.enqueueNDRangeKernel(
            kernel,
            cl::NullRange,
            cl::NDRange(width, height),
            cl::NullRange
    );

    // TODO set scene graph transformation
}