Aarrhhh, sorry, I’m so stupid. I was looking at looking at the image of the green tree and blue sky. But this is potrait format, so the camera was rotated, so the top-left pixel of the final image was the bottom-left pixel as recorded by the camera.
So the bottom-left 4 sensels as captured by the camera were:
b g
g r
After rotation, these become:
g b
r g
So the exif metadata is correct. The CFA really is [b g][g r]. That solves that problem.
The only problem is those four weird sensels in each 16x16 square. Ideally a raw processor would know what to do with them. If they are “white”, it could incorporate them into the demosaicing algorithm (but I don’t know how).
Next best: a raw processor would ignore the values in those sensels, treating them as having no R, G or B value, so these sensels need interpolated values for all three channels instead of just two. Again, I don’t know how.
Worst option: ignore the values in those sensels, but assume they should be Blue values, and make them the simple average of the four nearest Blue sensels. Then the image can be demosaiced in the usual way. And I can do that. The commands are for Windows BAT scripts.
Get the raw sensel values. However, dcraw re-orients to make the image “portrait”, even with the “-j” option:
set CAMERA_SRC=IMG_20191105_134321.dng
%DCRAW% -v -W -o 0 -6 -r 1 1 1 1 -g 1 0 -D -d -T -O cam_gray.tiff %CAMERA_SRC%
Make a list of options for exiftool:
(
exiftool -args -make -model %CAMERA_SRC%
echo -DNGVersion=1.4.0.0
echo -DNGBackwardVersion=1.3.0.0
echo -EXIF:SubfileType=Full-resolution Image
echo -PhotometricInterpretation=Color Filter Array
echo -IFD0:CFARepeatPatternDim=2 2
echo -IFD0:CFAPattern2=1 2 0 1
echo -Orientation=Horizontal
echo -BitsPerSample=16
echo -SamplesPerPixel=1
)>exifargs.txt
Note the CFA pattern is correct for this “portrait” image.
Make a 16x16 mask that is white where the sensels are weird, otherwise black:
magick ^
-size 16x16 xc:Black ^
-fill White ^
-draw "point 1,6 point 5,6 point 9,14 point 13,14" ^
m.png
This is correct for this “portrait” image. For other orientations, it should be rotated.
Do some magick on the image: transform from the range 0-1023 to 0-QuantumRange (eg 0-65535); make every pixel the mean of the four nearest pixels of the same channel; composite that over the original, with a tiled mask, so only the weird pixels are changed.
magick ^
cam_gray.tiff ^
-evaluate Multiply %%[fx:QuantumRange/1023] ^
( +clone ^
-define "convolve:scale=^!" ^
-morphology Convolve 5x5:%KNL% ^
) ^
-size %%[fx:w]x%%[fx:h] tile:m.png ^
-compose Over -composite ^
cam_gray2.tiff
Make this TIFF into a DNG:
del cam_gray.dng
exiftool -@ exifargs.txt -o cam_gray.dng cam_gray2.tiff
Finally, test the DNG by using dcraw to make a sRGB TIFF:
%DCRAW% -v -6 -T -O x.tiff cam_gray.dng
The result, x.tiff, is good, There is no visible pattern of repeating noise.
This is not a great solution. The code is klunky, and would be worse if we had to properly process camera rotations. It ignores the data that is in those 4 every 256 sensels, although this might be useful “white” data.
But it works.