BenJuan26 / OpenSkyStacker

Multi-platform stacker for deep-sky astrophotography.
MIT License
98 stars 14 forks source link

Slow RAW processing #37

Closed BenJuan26 closed 6 years ago

BenJuan26 commented 6 years ago

A typical call to processConcurrent() on a single light frame:

Function Duration (ms) Percentage of total
getCalibratedImage() 1548 73.9%
generateAlignedImage() 524 25%
add to working image 24 1.1%

Reading the image, applying the calibration frames, debayering, white balance, etc. is taking 75% of the processing time. Three times longer than alignment!

Within the call to getCalibratedImage(), the times look like this:

Function Duration (ms) Percentage of total
Setup, open file, unpack 93 6.1%
Calibration 18 1.2%
dcraw_process() 1326 86.4%
dcraw_make_mem_image() 42 2.7%
cv::Mat cloning, bit depth conversion 56 3.6%

Nearly all of the time is spent in dcraw_process(), which does the debayering, white balance, gamma, and whatever other processing it needs to do to get the image to its presentable form. So all in all, nearly 64% of the processing time is spent just converting the image from raw to bitmap. That's unacceptable.

Since this all resides within an external library, the chances of trying to improve it directly are slim to none. The best thing to do would probably be to find another way to read and process the image. I've made attempts to debayer and white balance with OpenCV (since we're using it already for everything else) but it never seems to turn out quite right.

If another library is used, an essential feature it will need to have is the ability to mess with the Bayer image before processing is done, since that's where we apply the calibration frames. Libraw graciously lets us manipulate the Bayer image directly and then do the processing on the modified version.

BenJuan26 commented 6 years ago

Did some profiling on LibRaw::dcraw_process(). Looks like this:

Function Duration (ms) Percentage of total
raw2image_ex() 22 2.9%
scale_colors() 72 9.7%
pre_interpolate() 5 0.7%
ahd_interpolate() 498 66.8%
convert_to_rgb() 148 19.9%

ahd_interpolate() is only one of many interpolation options, so it might be worth it to check out the other ones to reduce the processing time.

BenJuan26 commented 6 years ago

Added this line in getCalibratedImage() to bring the quality down to linear interpolation:

params->user_qual = 0;

That reduced the duration of dcraw_process() to an average of 440ms, a reduction of almost exactly 3x from the previous 1326ms. Need to compare how much this affects the final quality of the image. If the quality is satisfactory than the change should be applied. In the future it might be worth proving a user-selectable option for this.

BenJuan26 commented 6 years ago

The values for user_qual are documented in LibRaw's API documentation. It could be worth exposing those options in a drop down and setting the variable accordingly, but in my testing linear actually seems to look less artifact-y than the default value. That plus the time savings makes it a no-brainer. Gonna hardcode it to linear for the time being.