Author Topic: Memory Problems during Image Operations  (Read 5904 times)

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
Memory Problems during Image Operations
« on: 2009 June 11 02:55:27 »
Juan,

I am currently trying to write a script that does a number of image operations such as assign(), cropTo(), apply(...,add). According to PI, the images have the following characteristics:
- Canon 40D RAWs
- width/height: 3908/2602
- Channels: 3
- Datatype: i16
- size 58 MBytes (also matches the observations in the Windows task managers)

The memory consumption for the script editor or the PJSR compile&run, script GUI etc. seem to be neglidgible, but when the script executes, memory consuption explodes to 500 MBytes, and consequenty, PI gives up:

Code: [Select]
CcdParamsEngine.doFlat() entry
CcdParamsEngine.doImages() entry
CcdParamsEngine.doImages() image1.width, image1.height=3908,2602
CcdParamsEngine.doImages() image2.width, image2.height=3908,2602
CcdParamsEngine.doImages() sumImage.width, sumImage.height=0,0
CcdParamsEngine.doImages() sumImage.width, sumImage.height=0,0
CcdParamsEngine.computeTargetRect(),lengthFactor=0.1
CcdParamsEngine.computeTargetRect(),x0,x1,y0,y1=1758.6,2149.4,1170.9,1431.1000000000001
CcdParamsEngine.doImages() assign(Image1)
CcdParamsEngine.doImages() cropTo()1
CcdParamsEngine.doImages() assign(Image2)
CcdParamsEngine.doImages() cropTo()2
CcdParamsEngine.doImages() assign(cropped1)1
Basic CCD Params Script done
*** Error [000]: C:/PCLGeorg/scripts/BasicCameraParameters.js, line 251: out of memory

Could you have  a look at the code snippet attached below, to see what is going wrong there. What I am trying to do is to cut 10% of the central image region, and later do some statistical operations on that.

Thanks!

Georg

Code: [Select]
  this.computeTargetRect=function(image, lengthFactor){
      var width=image.width;
      var height=image.height;
      var newWidth=width*lengthFactor;
      var newHeight=height*lengthFactor;
      var targetRect=new Rect(newWidth,newHeight);
      targetRect.moveTo((width-newWidth)/2,(height-newHeight)/2);
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.computeTargetRect(),lengthFactor=",lengthFactor);
         console.writeln("CcdParamsEngine.computeTargetRect(),x0,x1,y0,y1=",
                           targetRect.x0,",",targetRect.x1,",",targetRect.y0,",",targetRect.y1);

      }  // if debugging

      return targetRect;
   }  //computeTargetRect()


   //compute derived images sumImage, diffImage
   this.doImages=function(image1, image2, lengthFactor, sumImage, diffImage){
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.doImages() entry");
         console.writeln("CcdParamsEngine.doImages() image1.width, image1.height=",image1.width,",",image1.height);
         console.writeln("CcdParamsEngine.doImages() image2.width, image2.height=",image2.width,",",image2.height);
         console.writeln("CcdParamsEngine.doImages() sumImage.width, sumImage.height=",sumImage.width,",",sumImage.height);
         console.writeln("CcdParamsEngine.doImages() sumImage.width, sumImage.height=",diffImage.width,",",diffImage.height);
      }  // if debugging
      var targetRect=this.computeTargetRect(image1,lengthFactor);
      var cropped1=new Image();
      cropped1.resetSelections();
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.doImages() assign(Image1)");
      }  // if debugging
      cropped1.assign(image1);
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.doImages() cropTo()1");
      }  // if debugging
      cropped1.cropTo(targetRect);
      var cropped2=new Image();
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.doImages() assign(Image2)");
      }  // if debugging
      cropped2.assign(image2);
      cropped2.resetSelections();
      cropped2.cropTo(targetRect);
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.doImages() cropTo()2");
      }  // if debugging
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.doImages() assign(cropped1)1");
      }  // if debugging
      sumImage.assign(cropped1);
      if ( DEBUGGING_MODE_ON ){
         console.writeln("CcdParamsEngine.doImages() apply(Add)");
      }  // if debugging
...
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: Memory Problems during Image Operations
« Reply #1 on: 2009 June 12 07:13:25 »
Hi Georg,

I have reproduced what you're trying to do in a simpler test script:

Code: [Select]
#include <pjsr/UndoFlag.jsh>

function MyTestThing()
{
   this.computeTargetRect = function( image, lengthFactor )
   {
      var k0 = (1 - lengthFactor)/2;
      var k1 = (1 + lengthFactor)/2;
      return new Rect( Math.round( image.width*k0 ),
                       Math.round( image.height*k0 ),
                       Math.round( image.width*k1 ),
                       Math.round( image.height*k1 ) );
   };

   this.doImages = function( image1, image2, lengthFactor )
   {
      // Cropping rectangle
   
      var targetRect = this.computeTargetRect( image1, lengthFactor );

      console.writeln( targetRect );

      // Cropped images

      var cropped1 = new Image( targetRect.width, targetRect.height, image1.numberOfChannels, image1.colorSpace );
      image1.selectedRect = targetRect;
      cropped1.apply( image1 );

      var cropped2 = new Image( targetRect.width, targetRect.height, image2.numberOfChannels, image2.colorSpace );
      image2.selectedRect = targetRect;
      cropped2.apply( image2 );

      // Show the cropped images

      var w1 = new ImageWindow( 1, 1 );
      w1.mainView.beginProcess( UndoFlag_NoSwapFile );
      w1.mainView.image.assign( cropped1 );
      w1.mainView.endProcess();
      w1.show();
      w1.zoomToOptimalFit();

      var w2 = new ImageWindow( 1, 1 );
      w2.mainView.beginProcess( UndoFlag_NoSwapFile );
      w2.mainView.image.assign( cropped2 );
      w2.mainView.endProcess();
      w2.show();
      w2.zoomToOptimalFit();
   };
}

var test = new MyTestThing;
test.doImages( ImageWindow.activeWindow.mainView.image,
               ImageWindow.activeWindow.mainView.image,
               0.5 );

As far as I can tell, the code above works fine. Note that you don't need to create a large image and then crop it. You can create a new image with the required dimensions and use image.selectedRect and Image.apply() to copy the desired region of the source image.

I don't know why your code is eating 500 MB. It is most likely a garbage collection issue, as happens frequently. I'd need to see your exact code to say something more specific, but have you tried putting some calls to gc() within your code?
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
Re: Memory Problems during Image Operations
« Reply #2 on: 2009 June 12 08:42:46 »
Juan,

thanks for the code snippet. Replacing the relevant section of the my code with your procedure resolved the problem. I guess, the issue is somewhere in the cropTo(), which is the main difference between our 2 codes.

For the moment: issue closed (but keep in mind that there is something there...).

Georg
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)