Weird stripes on 5D mark II raw

Started by ilia3101, October 07, 2018, 06:41:56 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ilia3101

Fixed my broken 5D mark II recently(motherboard replacement), and for some reason there are these stripes on raw sensor images:



https://drive.google.com/file/d/1wwG0XIgZ5-rplEpZsMhi1K_LvOI-DEx6/view?usp=sharing

It looks like really intense vertical stripes with some horizontal structure built in. Vertical stripe algorithm does not get rid of them fully :-\

They appear on raw photos and raw video. Adding any sharpening makes them really visible

Is this solvable with some sensor adjustments or register tweaks? Or is this camera(sensor) just a brick?

a1ex

My vertical stripe algorithm is specifically written for a defect that appears on 5D3 (variable column gain). There are 8 column readout circuits that operate in parallel, so that pattern is going to repeat every 8 columns. This algorithm does not apply to other defects (such as per-column offset) and it won't be optimal on other models with different number of readout circuits.

5D2 appears to read out 4 columns at a time: the pattern confirms this:

Quote from: a1ex on August 31, 2018, 07:48:13 PM
FPS timer A has a small quirk - one unit means 4 pixels on this camera

Which means there are 4 analog circuits, possibly with slightly different gains, so we have to adjust 4 column gains in order to fix this defect.

In octave (look up read_raw.m here on the forum):

a = read_raw('IMG_9689.CR2');

# extract a 1000x1000 section (500x500 each channel) that shows the defect
red = a(1501:2:2500,3001:2:4000);
gn1 = a(1501:2:2500,3002:2:4000);
gn2 = a(1502:2:2500,3001:2:4000);
blu = a(1502:2:2500,3002:2:4000);

imshow(gn1, [2000 3000])  # green1 channel, pattern visible, repeats every 2 columns
imshow(gn1(:,1:2:end), [2000 3000])  # half of green2 columns, looks clean

# assuming there's a gain difference
black = 1024;
gain_gn1 = median((gn1(:,2:2:end)(:) - black) ./ (gn1(:,1:2:end)(:) - black)); # 1.0154
# gain_gn1 = median((gn1(:,2:2:end)(:) - black)) / median((gn1(:,1:2:end)(:) - black)); # 1.0143
gn1(:,1:2:end) = (gn1(:,1:2:end) - black) * gain_gn1 + black; # adjust odd columns (1,3,5...) to match even ones (2,4,6...)
imshow(gn1, [2000 3000]) # looks clean now

# blue channel appears to use the same correction
blu(:,1:2:end) = (blu(:,1:2:end) - black) * gain_gn1 + black;

# for the red/green2 column: 1.0183 from G2, 1.0190 from red, with first method
# then, one has to sync the two greens, but I don't expect any surprises


Conclusion: this is, indeed, a column gain issue. I'd expect my vertical stripe algorithm to get rid of it, but didn't test (guess I need to convert this CR2 to MLV first). The above is roughly what that algorithm does. I can write down the details in a notebook like these if anyone finds it useful.

I can also figure out how to update the vertical gain parameters, too (details are somewhere in this topic and also here). Need to check whether the column gain properties are persistent or not (IIRC they are not, so we may need to set these gains at every camera startup, or figure out how to force a reflash). There is a set of gains for every single image capture mode (photo, x5, 1080p, 720p, crop and so on); luckily, the 5D2 has only 3 such modes.

Will think about it, but it's fixable. There might be some factory calibration procedure in the firmware, too, but I don't remember stumbling upon one yet. It's also true that, while examining the 5D2 firmware years ago, I didn't exactly know what I was doing :D

If you can't wait: grab adtg_gui and look for column gain registers (IIRC these are the DFE gains on 5D2, but I might be wrong).

ilia3101

Thanks, I will try out the octave code. EDIT: I can see now! Is it doing essentially the same thing as vertical stripe algorithm?

You are right cr2 is inconvenient :D here's an mlv

Quote from: a1ex on October 07, 2018, 09:35:50 PM
I'd expect my vertical stripe algorithm to get rid of it, but didn't test (guess I need to convert this CR2 to MLV first).
I used the vertical stripe option in MLV App, I think it's the same algorithm but I'm not sure.

Quote from: a1ex on October 07, 2018, 09:35:50 PM
I can also figure out how to update the vertical gain parameters, too (details are somewhere in this topic and also here). Need to check whether the column gain properties are persistent or not (IIRC they are not, so we may need to set these gains at every camera startup, or figure out how to force a reflash). There is a set of gains for every single image capture mode (photo, x5, 1080p, 720p, crop and so on); luckily, the 5D2 has only 3 such modes.
I would be on board with investigating this.

Quote from: a1ex on October 07, 2018, 09:35:50 PM
There might be some factory calibration procedure in the firmware, too, but I don't remember stumbling upon one yet.
I thought there might be something like that. I was leaving it on sensor clean for ages hoping it would engage :'(

Quote from: a1ex on October 07, 2018, 09:35:50 PM
If you can't wait: grab adtg_gui and look for column gain registers (IIRC these are the DFE gains on 5D2, but I might be wrong).
Very likely to happen

ilia3101

Hmm i checked vertical stripes again...

No correction


With vertical stripe correction:


It gets rid of vertical patterns, but there still seems to be a really fine grid structure (confirming what I thought I saw earlier). Could it be more than just column gain issues then?

It is not present on older MLVs I have.

a1ex

I have a feeling the latest mlv_dump has the vertical stripe fix broken. With an older one (mlv_dump_4k branch, 906696acccb7, before bouncyball's massive rework):


mlv_dump --dng M03-2206-short.MLV
...
Vertical stripes correction:
  1.00000  1.03970  0.97908  1.02393  0.99438  1.03635  0.97523  1.02068


With that correction enabled, the image looks good to me.


The first bad revision is:
changeset:   18872:78c4e8f422ff
branch:      crop_rec_4k
parent:      18635:01fc07461da5
parent:      18870:1723fc397404
user:        g3gg0
date:        Tue Jan 16 20:57:02 2018 +0100
summary:     Merged in bouncyball/magic-lantern/mlv_dump_cdng (pull request #841)


I've tried --force-stripes on 78c4e8f422ff; it doesn't seem to work, but it appears to run slower; what's going on?!

With stripe correction disabled, and "-b 14" on the new version, both mlv_dump versions (78c4e8f422ff aka "new" and 01fc07461da5 aka "old" or "right before bouncyball's changes) are writing the same raw data in the DNG (compared in octave). EXIF metadata is different, so I get different looks if I render them in ufraw for a comparison...

With stripe correction enabled, the raw output is different:

prctile((A-B)(:), [0 1 10 50 90 99 100])'
ans =
     0     0     0     3    35    57   251


Looks like dcraw renders both old and new DNGs in the same way (it doesn't care about different metadata). So, here it goes:

old-ns.ppm / jpg (old mlv_dump, no stripe correction)
new14-ns.ppm / jpg (new mlv_dump, 14-bit output, no stripe correction; same as above; identical MD5)

old.ppm / jpg (old mlv_dump, default settings)
new.ppm / jpg (new mlv_dump, default settings)
new14.ppm / jpg (new mlv_dump, 14-bit output)

I can see the fine pattern in the output from new mlv_dump after zooming to 300%. The stripe fix is working to some extent, but doesn't fully correct the issue.

I can not see any pattern in the output from old mlv_dump, but my pixel peeping skills are not the best.

Double-checking:

a = read_raw('new14-ns.dng');

# extract green channel for each column group
g1 = a(2:2:end,1:4:end);
g2 = a(1:2:end,2:4:end);
g3 = a(2:2:end,3:4:end);
g4 = a(1:2:end,4:4:end);

# compute the column gains (match everything to first column group)
black = 1792;
k = [1 median(((g1-black)./(g2-black))(:)) median(((g1-black)./(g3-black))(:)) median(((g1-black)./(g4-black))(:))];
# 1.00000   1.04030   0.97964   1.02433

# apply the correction
for i = 2:4, a(:,i:4:end) = (a(:,i:4:end) - black) * k(i) + black; end

# render the image (extremely hackish)
imwrite(uint16(a), "cor.pgm"); system("pgm2dng cor.pgm"); system('exiftool cor.DNG -ColorMatrix1="0.4716 0.0603 -0.083 -0.7798 1.5474 0.248 -0.1496 0.1937 0.6651" -ColorMatrix2= -ForwardMatrix1= -ForwardMatrix2= -AsShotNeutral="0.473635 1 0.624" -CalibrationIlluminant1=D65 -CalibrationIlluminant2='); system("dcraw -v -b 4 -g 1 1 -k 1792 -S 16200 cor.DNG");

# output nearly identical to old.ppm => the vertical stripe algorithm from old mlv_dump handles this particular image as expected.


cc @bouncyball (that's a bug report for mlv_dump on steroids).

ilia3101

Just tried it with an old mlvdump from 2016, and I can't see any patterns! So it is an issue with bouncyball mlv_dump code.
In your comparison of old and new stripe correction, the horizontal patterns I mentioned are slightly visible. Pretty strange bug. Hopefully bouncyball can fix it.

Also these patterns do not appear in jpeg at all, even with full sharpening and contrast in the picture profile. So could the camera be compensating?

a1ex

That means Canon's debayering algorithm might do some sort of gain balancing or at least green equilibration.

Danne

@Ilia3101
Could you upload your version of mlv_dump that works? Want too compare against my builds in Switch.
Isn't there at least two versions of vert stripe code floating around? Remember getting older code working better with dualiso files.

ilia3101

@Danne
The version I tested was actually downloaded from the first post in mlv_dump thread :D

From the zip file that contains versions for all platforms

@a1ex
Oh yeah probably is debayering algorithm, otherwise they would fix the raw as well.
I have noticed before that the debayering looks very much like bilinear with green channel smoothing of some kind (to get rid of the dots it has on edges). I had that in mlv app before it released but now I don't remember how to do that :(

Danne


bouncyball

@a1ex
Thank you for the tip.

Quote from: a1ex on October 07, 2018, 11:54:06 PM
I can see the fine pattern in the output from new mlv_dump after zooming to 300%. The stripe fix is working to some extent, but doesn't fully correct the issue.
Before merging mlv_dump used "fix_vertical_stripes()" function from raw2dng.c. Now it uses its own file called stripes.c which is the slightly modified (not algorithm, only some function parameters) version from MLVFS. I have to compare both. Until now it worked not bad.

@Ilia3101
Can you test your clip with MLVFS and share your findings?

ilia3101

Yes this 'broken' stripe fixer has worked well for subtle stripes which is most cases.

Will try out with mlvfs

Edit: didn't have time today -didn't get to try out mlvfs. I have an older version installed on my mac but I guess I need to install the newest one so will have to wait.

bouncyball

That part of MLVFS did not change since ages so you can try with what you've got.

bouncyball

@a1ex

Quote from: a1ex on October 07, 2018, 11:54:06 PM
I've tried --force-stripes on 78c4e8f422ff; it doesn't seem to work, but it appears to run slower; what's going on?!
This feature forces gain coefficient calculation for every frame. Someone asked for it while ago because he believed first frame of his footage was not good enough for coeff calculation. After adding this dumb option he sad he is satisfied with the result and does not care about the speed :)

a1ex

I know that; I was confused by the lack of a status message (the one with correction gains, present in older versions), and by the patterns being still visible after the correction. At first I thought it doesn't work at all (i.e. result discarded or something like that), though - from the execution speed - it was clear that some processing was being made.

Then I've made that comparison to figure out what's going on.

bouncyball

@a1ex

Quote from: a1ex on October 09, 2018, 04:54:36 PM
I was confused by the lack of a status message (the one with correction gains, present in older versions)
Oh, I got it, you have to specify "--dng --show-progress" and the older status will be printed (lots of other info will be printed after this).

bouncyball

New version prints this:


Vertical stripes correction: 'NEEDED'
  1.00000  1.00000  0.97897  0.98499  0.99390  0.99727  0.97475  0.98190

vs you posted above:

Vertical stripes correction:
  1.00000  1.03970  0.97908  1.02393  0.99438  1.03635  0.97523  1.02068

vs

# compute the column gains (match everything to first column group)
black = 1792;
k = [1 median(((g1-black)./(g2-black))(:)) median(((g1-black)./(g3-black))(:)) median(((g1-black)./(g4-black))(:))];
# 1.00000   1.04030   0.97964   1.02433


Definitely lots of difference between 2 versions.

bouncyball


ilia3101

Quote from: a1ex on October 07, 2018, 09:35:50 PM
If you can't wait: grab adtg_gui and look for column gain registers (IIRC these are the DFE gains on 5D2, but I might be wrong).

I have been trying out adtg_gui finally, and the DFE gains do seem to adjust column gain (I can create really intense vertical stripes). I can't see a way how I'd be able to fine tune it though, as the stripes are not visible at all on the camera (at the normal levels), I turned sharpening and contrast all the way up in picturestyle and still nothing, tried ML digital ISO in image fine tuning to -2 but this feature seems to not work now(cant make any of the image adjustments do anything)

And if I do find values that fix the stripes, is it possible to set these registers permenantly?

a1ex

You should be able to adjust them using the gains printed by mlv_dump (as I expect it to print roughly similar values). On 5D2, there are 4 analog circuits, mlv_dump prints 8, so I'd expect the first 4 values to match the last 4. For better accuracy, try a couple of sample files and average the correction values.

We'll need to figure out a couple of things:
- the order and the phase of these corrections (i.e. find out what register affects the first column, what register affects the second column and so on - trial and error, e.g. double (or halve) the value of one of these registers and write down what columns are affected;
- properties (likely photo vs movie mode, one for each ISO, see e.g. here or here or here);
- how to make persistent changes to these properties (IIRC they are not saved at every shutdown; worst case - reflash a small part of the ROM).

TLDR: it's doable, just requires some time to sit down and figure out the details.

ilia3101

Quote from: a1ex on January 20, 2019, 01:48:12 PM
You should be able to adjust them using the gains printed by mlv_dump (as I expect it to print roughly similar values). On 5D2, there are 4 analog circuits, mlv_dump prints 8, so I'd expect the first 4 values to match the last 4. For better accuracy, try a couple of sample files and average the correction values.

Good to know mlv dump should be usable for this. I don't actually know how vertical stripes work, are these gains linear? and do they start from black level or from zero in the raw?

Quote from: a1ex on January 20, 2019, 01:48:12 PM
We'll need to figure out a couple of things:
- the order and the phase of these corrections (i.e. find out what register affects the first column, what register affects the second column and so on - trial and error, e.g. double (or halve) the value of one of these registers and write down what columns are affected;

I will do so. Then I want to plot a graph for some different register values and resulting gain to see the relationship and get a formula. Or are these registers known to be proportional to the gain they control?

Quote from: a1ex on January 20, 2019, 01:48:12 PM
- properties (likely photo vs movie mode, one for each ISO, see e.g. here or here or here);

Hmm does the camera have separate gain settings for different ISOs as well? And would the gains really need to be very different for different ISOs? If they're at least close I would be happy just to calibrate on ISO 100 video mode.

Quote from: a1ex on January 20, 2019, 01:48:12 PM
- how to make persistent changes to these properties (IIRC they are not saved at every shutdown; worst case - reflash a small part of the ROM).

Hopefully doable

Thanks !@