X-trans support?

Hi,
I really hate asking this kind of question, but is there anybody able to work on X-trans raws support?
The issue is open here, and apparently it’s mostly a problem with black level reading (libRaw has been ruled out). I would help if I could, and I spent quite some time trying to figure out the code, but I don’t understand how it works.
X-trans cameras start to be more popular over the time, and I’m sure time spent on this issue would be worthy.

@sguyader Sébastien, please provide a series of two or three xtrans raw files. I will take a look then.

@sguyader Sébastien, this patch should give correct black levels for xtrans files.

diff --git a/src/RawParameters.cpp b/src/RawParameters.cpp
index a8b9b88..1b4b991 100644
--- a/src/RawParameters.cpp
+++ b/src/RawParameters.cpp
@@ -196,6 +196,12 @@ void RawParameters::fromLibRaw(LibRaw & rawData) {
     max = r.color.maximum;
     black = r.color.black;
     copy_n(r.color.cblack, 4, cblack);
+    if(r.idata.filters == 9) { //xtrans
+        for (int c = 0; c < 4; c++) {
+            cblack[c] = r.color.cblack[6];
+        }
+    }
+    std::cout << "black : " << cblack[0] << std::endl;
     adjustBlack();
     copy_n(r.color.pre_mul, 4, preMul);
     copy_n(r.color.cam_mul, 4, camMul);

Edit: for reference

2 Likes

@sguyader This patch may fix your issue (can’t test without examples)

diff --git a/src/ImageStack.cpp b/src/ImageStack.cpp
index 83d22e7..53ecb09 100644
--- a/src/ImageStack.cpp
+++ b/src/ImageStack.cpp
@@ -62,7 +62,7 @@ void ImageStack::calculateSaturationLevel(const RawParameters & params, bool use
     }
     satThreshold = params.max == 0 ? maxPerColor[0] : params.max;
     for (int c = 0; c < 4; ++c) {
-        if (maxPerColor[c] < satThreshold) {
+        if (maxPerColor[c] > 0 && maxPerColor[c] < satThreshold) {
             satThreshold = maxPerColor[c];
         }
     }
diff --git a/src/RawParameters.cpp b/src/RawParameters.cpp
index a8b9b88..b9d8c6c 100644
--- a/src/RawParameters.cpp
+++ b/src/RawParameters.cpp
@@ -196,6 +196,11 @@ void RawParameters::fromLibRaw(LibRaw & rawData) {
     max = r.color.maximum;
     black = r.color.black;
     copy_n(r.color.cblack, 4, cblack);
+    if(r.idata.filters == 9) { //xtrans
+        for (int c = 0; c < 4; c++) {
+            cblack[c] = r.color.cblack[6];
+        }
+    }
     adjustBlack();
     copy_n(r.color.pre_mul, 4, preMul);
     copy_n(r.color.cam_mul, 4, camMul);

https://github.com/jcelaya/hdrmerge/issues/112#issuecomment-373065034

2 Likes

Much thanks Ingo! It works fine. I don’t have great images to share for testing, the ones I have were taken handheld, so there are some misalignments, but the black levels are now set correctly.

2 Likes

Sébastien, ok to push it then?

Edit: I just pushed the fix.

1 Like

Hmmm… in fact I tried on a new set of 3 images, and it looks like the final DNG is mostly as dark as the darkest bracket. I’ll upload the set to filebin.

Edit: here’s the link to the images Filebin | gk09dzala7hlp1ec

Or maybe I don’t know how HDRMerge works really… When I open the DNG, it looks exactly like the darkest frame, but when I push the DNG by +4EV I get the same low noise in the shadows as the brightest frame, while pushing the darkest frame by +4EV brings out a lot of noise.

So, I guess it works, and that all I need to push the shadows in the merged DNG?

1 Like

Seems to work fine then.

I was expecting that the merged DNG would open with more of a “merged look” already, without the need to push the shadows.

That’s normal behaviour:
neutral

+4EV

Edit: Though I could try to improve that…

A “merged look” would be tone-mapping. HDRMerge produces raw files with a high dynamic range, it does not alter them.

If I compare the HDR DNG in RT to any of the source images used in the creation of that DNG, I can make the HDR DNG perfectly match any of the source images by using exposure compensation alone. That’s really cool. It means one can save a lot of disk space by merging all source raw files into one, and can still, for example, output {-4EV, -2EV, 0EV, 2EV, 4EV} from that single HDR raw file into TIFFs for use in Luminance HDR.

Yes, it was just a lack of understanding about what the merged DNG is. That’s great indeed, and I’m so happy to have this possibility offered now. Not only it can save space like you said, but it saves also some processing time for scenes with a dynamic range larger than what the sensor can handle.
I read the “manual” in the read me file at github, but it doesn’t explain how to use the files we get from HDRMerge.

1 Like

I’ll submit a pull request for that shortly :stuck_out_tongue:

2 Likes

I have a question, still regarding x-trans raws: I saw that the alignment of input files is made by translation by increments of 2 pixels because of the Bayer pattern… but x-trans being another CFA, what is consequence of moving frames by increments of 2 pixels?

The alignment for xtrans files is disabled here

Hopefully this is helpful: Update readme to say what to do with output images by paperdigits · Pull Request #121 · jcelaya/hdrmerge · GitHub

1 Like

@paperdigits thanks for the addition to the documentation. However, I think we need to go further. Indeed, the user is likely to know that they need to further process, because the resulting file is a raw file, and raw files always need to be processed. What is lacking in my opinion, is at least a simplified explanation of what can be done from the resulting DNG. For instance, I was (foolishly) thinking that when opening the DNG the shadows that are displayed in RT would be the shadows from the bright exposure, the highlights those from the dark exposure, and that the processing left would more tweaking the local and/or global contrast. Maybe I’m not the only one to be foolish like that, and explaining what to do would prevent seeing foolish questions in the future?
As for where such a how-to should be written, I don’t know.

Why not on the main PIXLS.US site? :wink:

@sguyader the manual is on the website, HDRMerge