5
\$\begingroup\$

I have to apply window leveling on Canvas Medical Image (CR). I have to get a pixel array from C# Component.lutArr, which is a lookup table array coming as a C# component and which I use in JavaScript. On click of the button, I have to call the function ApplyWLCust(). In this function, all process done getting result perfect. For window leveling, use bit shifting, which takes around 585ms. I have to reduce this time. What should I do?

var imagewc = document.getElementById("text1").value;
                var imageww = document.getElementById("text2").value;     
pixelArr = [11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11..]  
        if (pixelArr != null)
                {
                    for (var i = 0, n = pixelArr.length; i < n; i++)
                    {
                        pix = pixelArr[i];
                        pix = ApplyWL(pix, imagewc, imageww);
                        pix = lutArr[pix];



                    // var red = (pix & 0x00ff0000) >> 16;
                    v = i * 4;
                    imagedata[v] = pix & 0xff;
                    imagedata[v + 1] = (pix >>> 8) & 0xff;
                    imagedata[v + 2] = (pix >>> 16) & 0xff;
                    imagedata[v + 3] = 255;
                }
                //  offscreenCtx.imageSmoothingEnabled = true;
                offscreenCtx.putImageData(g, 0, 0);
            }
function ApplyWL(value, _valwindowCenter, _valwindowWidth)
        {
            Recalculate(_valwindowCenter, _valwindowWidth);
            if (value <= _windowStart)
                value = _minimumOutputValue;
            else if (value > _windowEnd)
                value = _maximumOutputValue;
            else
            {
                value = Math.round((((value - _windowCenterMin05) / _windowWidthMin1) + 0.5) * 255.0);
            }
            return value;
        }

        var _minimumOutputValue = 0;
        var _maximumOutputValue = 255;
        function Recalculate(_valwindowCenter, _valwindowWidth)
        {
            if (!_valid)
            {
                _windowCenterMin05 = _valwindowCenter - 0.5;
                _windowWidthMin1 = _valwindowWidth - 1;
                _windowWidthDiv2 = _windowWidthMin1 / 2;
                _windowStart = (_windowCenterMin05 - _windowWidthDiv2);
                _windowEnd = (_windowCenterMin05 + _windowWidthDiv2);
                _valid = true;
            }
        }


Width<input id="text1" type="text" />
    center<input id="text2" type="text" />
    <input id="Button1" type="button" value="Apply" onclick="ApplyWLCust();" />
    </br> time required<input id="text3" type="text" />
    <canvas style="height: 500px; width: 500px; display1: none; background-color: black;
                border: 1px solid red;" id="offscreenCanvas">
\$\endgroup\$
2
\$\begingroup\$

I think we need more code,

  • Where are imagewc, imageww, and lutArr defined ? Those are all 3 unfortunate variable names by the way

Regardless, I think a large speed up should be gained from calling Recalculate once before the loop on pixelArr since imagewc and imageww never change in that loop.

Furthermore, since value is cut of between 0 and 255, you should pre-calculate the array of values.

var lookup= [] , i;
for( var i = _minimumOutputValue  ; i < _maximumOutputValue+1; i++ )
    lookup[i] = Math.round((((i- _windowCenterMin05) / _windowWidthMin1) + 0.5) * 255.0);

then your function would be:

function ApplyWL(value, _valwindowCenter, _valwindowWidth)
{
   if (value <= _windowStart)
     return lookup[_minimumOutputValue  ];
   if (value > _windowEnd)
      return lookup[_maximumOutputValue];
   return lookup[value]
}

I might be wrong about the ranges of lookup, your table might have to be larger, but I am sure you realize the value of a lookup table at this point.

EDIT:

I wrote some code to look at it, some notes: * I moved the variables to the top, please make sure that all variables are declared with var * Only constructors should start with an uppercase letter

var imagewc = document.getElementById("text1").value,
    imageww = document.getElementById("text2").value,
    _minimumOutputValue = 0,
    _maximumOutputValue = 255,    
    _valid,
    cacheWL = [],
    pixelArr = [11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11]; 

if (pixelArr != null)
{
  //Move this out of the for loop
  recalculate(_valwindowCenter, _valwindowWidth);
  //Then set the cache which needs the results of `recalculate`
  cacheWL();
  for (var i = 0, n = pixelArr.length,v = 0,i < n; i++)
  {
    pix = pixelArr[i];
    pix = ApplyWL(pix, imagewc, imageww);
    pix = lutArr[pix];

    imagedata[v] = pix & 0xff;
    imagedata[v + 1] = (pix >>> 8) & 0xff;
    imagedata[v + 2] = (pix >>> 16) & 0xff;
    imagedata[v + 3] = 255;
    //Instead of doing a multiplication, you can keep adding 4
    v += 4; 
  }
  offscreenCtx.putImageData(g, 0, 0);
}

function setCacheWL()
{
  for( var i = _minimumOutputValue ; i <= _maximumOutputValue ; i++ )
    cacheWL[i] = Math.round((((i - _windowCenterMin05) / _windowWidthMin1) + 0.5) * 255.0);
}


function ApplyWL(value, _valwindowCenter, _valwindowWidth)
{
   if (value <= _windowStart)
     return cacheWL[_minimumOutputValue];
   if (value > _windowEnd)
      return cacheWL[_maximumOutputValue];
   return cacheWL[value]
}

function recalculate(_valwindowCenter, _valwindowWidth)
{
  if (!_valid)
  {
    _windowCenterMin05 = _valwindowCenter - 0.5;
    _windowWidthMin1 = _valwindowWidth - 1;
    _windowWidthDiv2 = _windowWidthMin1 / 2;
    _windowStart = (_windowCenterMin05 - _windowWidthDiv2);
    _windowEnd = (_windowCenterMin05 + _windowWidthDiv2);
    _valid = true;
  }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.