template<typename scalartype> static int getRGBMax(vtkImageDataPtr image) { int max = 0; vtkImageIterator<scalartype> iter(image, image->GetExtent()); while (!iter.IsAtEnd()) { typename vtkImageIterator<scalartype>::SpanIterator siter = iter.BeginSpan(); while (siter != iter.EndSpan()) { int value = *siter; ++siter; value += *siter; ++siter; value += *siter; ++siter; if (value > max) { max = value; } } iter.NextSpan(); } return max/3; }
vtkImageDataPtr USFrameData::useAngio(vtkImageDataPtr inData, vtkImageDataPtr grayFrame, int frameNum) const { // Some of the code here is borrowed from the vtk examples: // http://public.kitware.com/cgi-bin/viewcvs.cgi/*checkout*/Examples/Build/vtkMy/Imaging/vtkImageFoo.cxx?root=VTK&content-type=text/plain if (inData->GetNumberOfScalarComponents() != 3) { if(frameNum == 0) //Only report warning once reportWarning("Angio requested for grayscale ultrasound"); return grayFrame; } vtkImageDataPtr outData = vtkImageDataPtr::New(); outData->DeepCopy(grayFrame); // outData->Update(); // updates whole extent. // printStuff("Clipped color in", inData); // printStuff("Grayscale in", outData); // int* inExt = inData->GetWholeExtent(); int* outExt = outData->GetExtent(); // Remember that the input might (and do due to vtkImageClip) contain leaps. // This means that the wholeextent might be larger than the extent, thus // we must use a startoffset and leaps between lines. unsigned char *inPtr = static_cast<unsigned char*> (inData->GetScalarPointerForExtent(inData->GetExtent())); unsigned char *outPtr = static_cast<unsigned char*> (outData->GetScalarPointerForExtent(outData->GetExtent())); int maxX = outExt[1] - outExt[0]; int maxY = outExt[3] - outExt[2]; int maxZ = outExt[5] - outExt[4]; Eigen::Array<vtkIdType,3,1> inInc; inData->GetContinuousIncrements(inData->GetExtent(), inInc[0], inInc[1], inInc[2]); CX_ASSERT(inInc[0]==0); // we assume (wholeextent == extent) for the outData in the algorithm below. assert here. Eigen::Array<vtkIdType,3,1> outInc; outData->GetContinuousIncrements(outData->GetExtent(), outInc[0], outInc[1], outInc[2]); CX_ASSERT(outInc[0]==0); CX_ASSERT(outInc[1]==0); CX_ASSERT(outInc[2]==0); for (int z=0; z<=maxZ; z++) { for (int y=0; y<=maxY; y++) { for (int x=0; x<=maxX; x++) { //Look at 3 scalar components at the same time (RGB), //if color is grayscale or close to grayscale: set to zero. if (((*inPtr) == (*(inPtr + 1))) && ((*inPtr) == (*(inPtr + 2)))) { (*outPtr) = 0; } else { // strong check: look for near-gray values and remove them. double r = inPtr[0]; double g = inPtr[1]; double b = inPtr[2]; int metric = (fabs(r-g) + fabs(r-b) + fabs(g-b)) / 3; // average absolute diff must be less than or equal to this // std::cout << QString(" %1,%2,%3 \t %4, %5 -- %6").arg(int(inPtr[0])).arg(int(inPtr[1])).arg(int(inPtr[2])).arg(idxR).arg(idxY).arg(metric) << std::endl; if (metric <= 3) (*outPtr) = 0; } //Assume the outVolume is treated with the luminance filter first outPtr++; inPtr += 3; } inPtr += inInc[1]; } inPtr += inInc[2]; } return outData; }