I've started working on a hack for the 6s Plus.
Up to now, I've realized the NoiseReductionMethod you referred to only decreases color noise reduction a bit when set to 0. The very strong (and this is the main problem!) luma noise reduction isn't decreased when using 0 instead of 3.
Will keep you posted.
Continued (again, iPhone6s+ only!) at 12/04 21:33EET: the NoiseReductionMethod value 1 similar to the 0 case: it only changes CNR. However, it applies slightly more agressive CNR as the 0 case (but still less than the 2/3 case, see below). This also means any
LumaDenoiseStrength hacks are ignored, which also means you do NOT want to use these 0/1 values at all.
The NoiseReductionMethod value 2 seems to be the same as the default 3: very strong CNR (much stronger than the 0/1 cases above) but decreased LumaDenoiseStrength values do have an effect on the LNR.
Continued (again, iPhone6s+ only!) at 12/04 22:00EET: I've completely get ridden of CNR (but not LNR as yet) by changing all
ChromaDenoiseStrength reals to 0.15 and integers to 1. When doing exactly the same for
LumaDenoiseStrength, the LNR is decreased but, unfortunately, not that much. (Still, it's better than the default because of the less smearning.) Will keep you posted.
Continued (again, iPhone6s+ only!) at 12/05 00:23EET:M y new findings:
there are several arrays named "
LumaDenoiseStrength" and "
ChromaDenoiseStrength". You'll want to hack these. Let's start with the former as it's much more complicated.
If you put the same values in all the values of all LumaDenoiseStrength arrays (there are several of them, totalling 256 real and 22 integer values), keeping the real vs. integer distinction:
a, 0.15 for reals, 1 for integers: everything will work with slightly (not much, but it certainly helps!!) less LNR except for scenes with brightness above 12. (In my tests, around 12 did I start getting messed-up images. All images having significantly less brightness were OK. The lowest non-working value I found was 11.77.)
b, 0 for everything: never worked in very low light (tested with brightness values 1624-5000)
c, 0.1 for reals, 1 for ints: the threshold is around 11 (the highest/lowest good/bad brightness was 11,48 and 10.93, respectively)
d, values under 0.1 were generally useless even in very low light (I'll play with them though).
It certainly seems the array indexes represent in?de?creasing brightness values. That is, giving the same values won't have the best result.
Let's talk about CNR and "
ChromaDenoiseStrength" now. The situation is far better than with LNR: if you change all array elements (there is exactly 100 of them if you count reals and ints together) 0.15 will result in applying almost no CNR, resulting in significantly less pale colors in low light. (Of course, you'll have a LOT of CN then; even at base ISO in the shadows, as you may have already guessed.) That is, just override these values.
I'll continue reporting. And, again, this all applies to the 6s+ only, albeit the iPhone 6 may need to use the same values.
Continued at 12/05 12:48EET: Now I've found the block tuning the LNR for the panorama mode. It's under
NR2Parameters_Panorama and has the same structure as other
NR2Parameters<_possible postfix> arrays: there are some (here, four) "Bands" taking up much of the code.
Modding the
LumaDenoiseStrength array values of the first "
Bands" element (e.g., zeroing all out) has no effect on anything. Doing the same to the second, however, changes everything: all brightness combinations (low light (tested with brightness around 3) / intemediate (brigtness around 7.8) / bright (brigtness around 11.5)) are changed.
1, By zeroing all these values out,
none of the three configs work (all the three images are messed up), as one should suspect based on my previous posts.
2, I tried changing the indices 3, 5, 7 and 9 to (integer) 1 -
no effect (same over-LNR'ed images as with the default config)
3, changing the first and last reals to 0.101 did work, however - the image became much (luma) noisier and somewhat (but not much) less blurry.
That is, we're on the right track. Now it's far easier to supply different parameters in here to see what happens - as only one "Bands" element need to be examined (I assume the changes here could equally be applied to other
NR2Parameters<_possible postfix> / LumaDenoiseStrength's.)
Continued at 12/06 01:01EET:
1, I was wrong about the first band not being used in
NR2Parameters_Panorama. It is used; by overriding the four values of the
ChromaDenoiseStrength array there with, say, 0.1, this can be seen. (Albeit the effects are in no way as strong as doing the same to Band 2 values.)
2, the third array in these bands,
LumaRemixWeight, directly changes post-sharpening. For example, with the generic value of 0...0.1, the pano becomes quite soft; with 10 (much higher than the original), absolutely awful with oversharpening artifacts. Unfortunately, it's insufficient to properly get rid of the LNR artifacts.
3, I've created an Xcode project for quickly changing the parameters in the pano. It GREATLY speeds up hacking - no longer will you need file transfers and, what is more, restarting the entire device! Yes, the
setuid(0); system("killall Camera"); I mentioned earlier in the thread does work - unlike with just killing the camera from the stock handler. This means you only need to run my app once and the changes will be seen by the Camera app after you resume it.
To run it,
a, simply give write rights to the single
CameraSetup.plist file. (The encompassing directory's flags need not be changed.) Repeat this every time you externally(!) overwrite the file from, say, iExplorer.
b, if you have a 6s+, you may not need to change "
n66" to some other value in the
"NSArray* dirNameArr = @[@"N66" ];" instruction. On non-GSM models, it may be in a different directory. Change the name in the instruction.
c, if you do NOT have a 6s+, do NOT run the app directly before carefully changing:
1, the default values
2, the number of array elements
3, etc.
It's pretty straightforward.
d, my code currently supports overwriting all the three arrays in the second and the luma/chroma arrays in the first band. (Will add support for the third band.) With the luma values, you can supply both the same value for all entries or define dividers so that the original value divided by this value are written back to the arrays.
e, by default, it just writes back the default values to these 3+2 arrays. Change "
BOOL RESTORE_DEFAULTS = YES;" to
NO if you want to actually apply your changes.
The Xcode project is at
https://www.dropbox.com/s/2bu0arp2vrufccf/iPhone6sPlusCameraEnhancer-01.zip?dl=0 . Will post new links to future versions in my future post updates.
Note that I just modded my earlier "
VideoBitrateConfigurer" app's source. The vast majority of the legacy code isn't executed - look for "
return" in
VideoBitrateConfigurerViewController.viewDidLoad(). I just didn't have the time to remove the unneeded legacy code.
Continued at 12/06 15:46EET:
1, Just posted a new, fully cleaned up and, now, 4-band (that is, now, all bands are handled in
NR2Parameters_Panorama) version of the app to
https://dl.dropboxusercontent.com/u/81986513/iPhone6sPlusCameraEnhancer-02.zip . Delete the previous version, this one is much better!
All you'll need to fine-tune is in
VideoBitrateConfigurerViewController.m's
viewDidLoad method.
The first, brand new section of the method defines a bunch of
a,
BOOLeans and
b,
double values.
BOOLs let for
1, assigning a single value for all four blocks. Separate values can be defined (these are three of the double's) for the three kinds of groups (luma/chroma/remix).
2, with luma only, using a divider to be applied on the original value.
doubles let for
1, as explained above, assigning a single value for the targeted array type of the four blocks
2, setting the divider value.
There is a quick shorthand BOOL, RESTORE_DEFAULTS, which, when given a value of YES, the app will restore all the original values and gets rid any of the previously modified values (by the app) completely.
2, I still haven't managed to find the configuration section responsible for the massive LNR. Even the lowest possible values (wired-in: around 0.15; divider: around 40) still not overdriving (see my previous posts on the bright scenes producing useless / "negative-like" images) the engine will not help the input, which is hopelessly blurred.
I've also played with the opposite: very high wired-in values. For example, 99999999999 results in a whopping 50-pixel-wide smearing area (with a very visible "glowing" ("dreamy") effect).
3, for
Chrome, the current 0.06 seems to be the best (the lower the better (less CNR); however, even lower values like 0.02 will result in a complete mess (fully greenish scene)). However, now that I still don't know how to fix the underlying blurring, reducing CNR won't be as useful as with, say, the raw-like JPG images of the Note4. (Please see
http://forum.xda-developers.com/note-4/general/shooting-light-best-image-quality-note-4-t3012008 for more info on this.)
4, for
Remix, around 1 is the best (or the original values). These values don't seem to be worth playing with.
I continue playing with these values and will add support for changing other values in the plist file. Nevertheless, feel free to give my current app a try if you want to experiment too. Again, it seems the underlying LRN is set elsewhere, not in these arrays; that is, your experiments will most likely turn out to be futile. However, I may be wrong (fingers crossed!).
Continued at 12/07 00:46EET:Continued playing with the values.
1, in
NR2Parameters_Panorama,
I experienced with only keeping one (the first) band (I deleted the three other ones): visibly more CN (without hacking any value). Hacking this to the current wired-in + divider values doesn't help.
When dropping the last three bands, color smearing becomes much more pronounced, mostly because of "
NR2Parameters_Panorama>GammaC". The default
gammaC = 0.45 must be decreased to around 0 to avoid color smearing. (Nevertheless, it doesn't help luma smearing.)
With the four original bands in Bands:
a,
GammaY (defeault: 0.52): 0.001: no visible change? 1000: same effect as very high (e.g., 99999999999)
LumaDenoiseStrength values: glowing. Negative values: messup
b,
GammaC: this is directly connected to CNR. With 0: much more CN here. Unlike with the one-band case, the default gammaC = 0.45 doesn't result in any major color bleeding
c,
SlopeFactor (def: 30): 0: no visible change
I've only tested the
BandFactorC, LensShadingFactorLuma, BiasFactor and
BandFactorY in one-Bands mode. See the comments in the code for more info. I haven't found them to be able to get rid of the LNR in there.
2, I've played with the other
NR2Parameters_<postfix> dictionaries under
0x0247 (
NR2Parameters, NR2Parameters_LongShort, NR2Parameters_TMBNR_SIS, NR2Parameters_TMBNR_LongShort). I've set the
GammaY of each of these dictionaries to -1 and looked for the camera modes (pano vs still vs. square vs. video modes) to see which camera mode uses the given dictionary. (That is, which produces immediately bad - greenish, inverted etc. - results.) I coulnd't find any - it seems these aren't used?
3, I've played the following values directly
in 0x0247 (with everything else intact; tests were done in pano and still mode, with both low- and bright light shots):
a, MicronsPerPixel (default = 1.22): no effect of increasing it to 4
b, the
SharpnessValue array (with 4 integers, all 128 by default): little (if any!) effect in stills mode: 0: a bit less sharpened than the def 128. Pano mode seems to be a bit more affected.
c, VISRenderMethod (default = 1): tested with 0, 2, 3 - no changes.
4, the framework for all these experiments are to be found in the latest version of my app with default values for easy default re-setting. Look for the fully commented-out code just before the
first occurrence of "
NR2Parameters_Panorama". Based on the key names above, you'll easily identify everything. Link:
https://dl.dropboxusercontent.com/u/81986513/iPhone6sPlusCameraEnhancer-03.zip
Continued at 12/11 20:46EET: Continued hacking.
1, I couldn't find any effects on the still image quality or the black curve form (shot in the default Photo mode) of the following values, all directly under *0x0247* (that is, the back camera entry):
ChromaNoiseReduction with three key/value pairs
ToneCurvesBlack
I also re-tested all the sub-0x0247 parameters I spoke about earlier (
NR2Parameters, NR2Parameters_LongShort, NR2Parameters_TMBNR_SIS, NR2Parameters_TMBNR_LongShort - all tested with
gammaY; the four values of the
SharpnessValue array;
VISRenderMethod) - none of them had any effect.
That is, currently, I don't know how the still camera can be hacked. Note that I also tried to apply the same changes to the
CameraSetup.plist file in
N66m (the other subdirectory with camera plists, in addition to our
N66) - no success.
2, however, I have some very good news! Yes, I've been able to make the LNR(!!!) in the pano mode significantly lower!
You'll need to change the following two values under
NR2Parameters_Panorama:
GammaY (default: 0.52): this sets the LNR level - the higher the value, the stronger the LNR. You can safely set it to 0, it'll have the least LNR while still being stable, that is, able to shoot any scene.
Note: it can be negative but, then, panos shot of dark(er) scenes will be messed up; that is, you'll only be able to shoot panos in good light. And, in my tests, even the lowest possible value (for example, for the brightness level of exactly 8.29, -0.745) couldn't deliver better results than 0.
GammaC (default: 0.45): this sets the CNR level - the higher the value, the stronger the CNR. As with GammaY, you can safely set it to 0.
The results are very good in good light. (In very low light, it doesn't help much.)
This is the default 0.52 / 0.45 case with very strong LNR and CNR (make absolutely sure you do compare these three images to each other!):
https://dl.dropboxusercontent.com/u/81986513/IMG_2100 all default.JPG
This is the gammaY = 0 case with default (very strong) CNR (0.45):
https://dl.dropboxusercontent.com/u/81986513/IMG_2102 gammaY = 0 .JPG
And this is the one with the least NR (gammaY = 0 and gammaC = 0) and by far the best detail retention:
https://dl.dropboxusercontent.com/u/81986513/IMG_2101 gammaY = 0 gammaC=0.JPG
Here's the latest version of my app, which sets these two parameters without any manual setup:
https://dl.dropboxusercontent.com/u/81986513/iPhone6sPlusCameraEnhancer-04.zip
(Again: you must give the file other write rights before running the app! And, again, it's applicable to the 6s+ only, albeit it should run on other models with very small modification.)
I've streamlined / cleaned up the code and added the new keys/values I talked about above.
Continued at 12/12 13:00EET: Today, so far, I've tested the following:
1, is there indeed any difference in in-motion (true) panos? The shots posted yesterday were taken with a 6s+ strictly fixed (I just tapped the shutter button to start taking the pano and, then, immediately tapped it to stop taking; that is, I didn't move the iPhone in between). Today, I did shoot an about 135 degree pano, focussing(*) on the Christmas hat. The hat was around halfway in the pano and about 3-4 feet from the iPhone.
*: technically, before starting to take the panos, I pre-focussed on another subject in the same focal plane (same distance from the turning axis) at startup so that I don't need to start with the hat itself. This way, I also avoided the problem of the first frame(s) possibly being of higher quality the in-motion ones, probably being imported from the camera verbatim, not by any kind of averaging / interpolation.
BTW,
why did I choose a Christmas hat? Because it has low-contrast, high-detail texture, which is excellent for noise reduction testing as exactly this (low-contrast, high-detail texture) that noise reduction algorithms blur away.
The results are satisfying: the difference is certainly visible in true panos, not only static ones like the ones posted yesterday. Let me show you two lower-light, low-constrast crops certainly demonstrating this:
Default configuration:
https://dl.dropboxusercontent.com/u/81986513/122015/20151212hat-in-motion-default.jpg
GammaY = GammaC = 0 (the ones recommended yesterday):
https://dl.dropboxusercontent.com/u/81986513/122015/20151212hat-in-motion-gammas-zero.jpg
Pay particular attention to the upper half of the hat - the difference in content resolving is obvious.
2, I played with additional hacks to my yesterday's
GammaY = 0 and
GammaC = 0 recommendations. I tried decreasing all the values of all the
LumaDenoiseStrength arrays of all the four bands.
As opposed to the original GammaY = 0.52, GammaC = 0.45 case (where a constant of 0.15 or a divider of 40 worked for most brightness setups), I needed to use much higher values to avoid completely messed-up scenes. With divider, the highest value (resulting in the lowest array element values) was 9. (10 has already caused messed-up images.) The code configuring this:
OVERWRITE_ALL_LUMA_VALUES_DIVIDER = YES;
allDivider_4th_band= allDivider_3rd_band= allDivider_1st_band= allDivider= 9;
As opposed to the original
GammaY = 0.52,
GammaC = 0.45 vs. hacked
GammaY = 0,
GammaC = 0 case I spoken of above, I couldn't find any differences between the images with the original and the this way hacked
LumaDenoiseStrength arrays. Just compare the following in-motion panorama crop of exactly the same subject (the hat):
https://dl.dropboxusercontent.com/u/81986513/122015/20151212hat-in-motion-gammas-zero-divider-9.jpg
That is, it seems it's absolutely futile to try to hack these
LumaDenoiseStrength arrays now, with the yesterday-recommended
GammaY = 0,
GammaC = 0 hacks.
(Note that I've shot several other panos for testing with the same setup. The results were exactly the same; that is, the differences are not simply sample variance / luck / difference in focussing etc.)
3, I've also directly compared the TIFF output of one of the TIFF-capable camera apps,
Camera+. In a nutshell: they are as noise reduced as stock JPEG's and just can't get rid of the NR. See
https://forums.macrumors.com/thread...pect-of-camera-s-645-pros-tiff-files.1944202/ for more info (along with test shots of the same hat).
Continued at 12/12 14:00EET: I've remade my tests with
TuningParameters>NoiseReductionMethod in the
N66 directory with an otherwise fully intact plist (no other hacks were applied). Just add the following code snippet to my code to remake them if you want:
int NoiseReductionMethod = 3;
if (SET_NONARRAYS)
{
//NoiseReductionMethod = -9999;
NSLog(@"NoiseReductionMethod: %@", [tuningParameters_1st objectForKey: @"NoiseReductionMethod"]);
}
[tuningParameters_1st setObject:[NSNumber numberWithInt:NoiseReductionMethod] forKey: @"NoiseReductionMethod"];
I've tested all integers between -1 and 5 (inclusive) and also -9999.
In stills, I couldn't spot any difference. In panos, only 2 and 3 worked: all other values produced a fully messed-up, useless image. There was absolutely no difference between method 2 and 3.
I've re-run the same tests with the same file in the
N66m folder. Absolutely no differences. The pano mode surely doesn't use this file at all as setting the gammas to zero here didn't have any effect on the NR in the pano mode, unlike with the N66 file. That is, it seems nothing uses this file.
Continued at 12/12 22:40EET: I posted some remarks on
AVCaptureSession.plist, that is, the plist setting some of the video recording parameters, to
#44
Continued at 12/15 17:40EET: I posted some additional real-world pano comparisons
to
#49 and
#50
Continued at 12/23 01:40EET: well-lit pano comparisons at
#57