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); }
/* 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 ); } } } }
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 }