Contact
Channels:  Pm  P-C  CH  HCw  Hmii  Mag  Lasco  |  Blog 
 
P.A.Semi

Channel CoroHole

This image format emphasizes darker features of Solar coronal clouds...


These images are combined from SDO/AIA 193 and 171 channels to highlight darker features in Solar Coronal clouds, best visible in channel 193, but they differ also in other channels and combining more of them reveals differences in various "shades" and structures in Solar Corona...


The gray background is from 193 WhiteEx component, which has white background for printing, and in order to emphasize darker regions, there is no huge dark space around...


Original images 193 and 171 from NASA/GSFC :

 


Combined CH image, and an image illustrating contribution of both components:

 
On the right image, one third of each source image has been erased before processing, so that left part shows contribution from 193 WhiteEx image, right shows contribution from 171 image, and in middle as it is combined...


In this example, the Twitter-like bird at the center is much better visible in CH composite image, than in each of the source images, but it can be confirmed from both originals...


Often the difference between used 171 and 193 images is 10 minutes and it does not matter much, since the Solar clouds change in hours and days, but each following 10-minute image differs only little, beside various eruptions, which are not much visible in this image format anyway... There is another format PmCh2 derived from this which combines both lighter and darker features well...


Code to generate this type of image in EvalScript language is below...

(For orientation in code, note that B objects are Bitmap32 created by NBm(w,h) or LoadImage(file), F objects are FloatMap (2D, 32-bit float per pixel) created by NFm(w,h) ...) 


#include FlowLib
#include "Eit195.lib"

SetJpegQuality(92);

EnumFileGroups('C:\Path\*0193.jpg','C:\Path\*0171.jpg',Perform,20/1440);

function Perform(Item193,Item171){
var In193:=Item193.File, In171:=Item171.File;
var Tc:=(Item193.Time+Item171.Time)/2;
var Out:=PCat(OutPath,FDt(Tc,'yyyymmdd_hhnn')+'_Mix171+193.jpg');
if(dbg) Out:=ChExt(Out,'_dbg.jpg');
//

if(FileExists(Out))return;
if(FileExists(PCat(ExFPath(Out),'Bad',ExFName(Out))))return;

// Load 171 (golden)
var B171:=Ldi(In171);
function Ldi(N){L('Loading: '+N);return LoadImage(N)}

// For illustrative purposes, erase some part of 171 and another of 193
if(dbg){
var x:=Round(B171.Width*0.333);
B171.FillRect(0,0,x,B171.Height,'#000000');
}

// Sharpen 171

var B171b:=Sharpen2_Bmp(B171.Clone(),1.414,2);

// Swap channels:
var w:=B171b.Width,h:=B171b.Height,Fr,Fg,Fb;
B171b.ExtractRgb(Fr:=NFm(w,h),Fg:=NFm(w,h),Fb:=NFm(w,h));
Fr.Sqr();
B171b.CombineRgb(Fb,Fg,Fr);

var B193;

// Load 193.WhiteEx
if(IcPos('HC',In193))B193:=Ldi(In193);
else{
L('Loading: '+In193);
B193:=TestHeqHc(In193,0.25); // auto WhiteEx ...
}

if(dbg){
var x:=Round(B193.Width*0.67);
B193.FillRect(x,0,B193.Height,B193.Width,'#000000');
}

// Merge:

B171b.MasterAlpha:=144/255;

var F:=NFm().Assign(B171b);
F.Offset(0.7).Clip(0,1);
B171b.WriteChannel(3,F); // alpha
B171b.DrawMode:=dmBlend;

B193.Draw(0,0,B171b);

// Gamma 86, Contrast 102
B193.Contrast(102);
B193.Gamma(86);

// Output:
//ViewBitmap(B193);

L('To: '+Out);
if(!B193.SaveToFile(Out)){
L('Save failed!');
Abort();
}
L('');
}

The WhiteEx component is rendered by Eit195.lib function TestHeqHc (Histogram Equalization, High Contrast) ... These images are available in Heliograf in Channel HCw ...


function LoadEit195(JpgFile) {
// Loads Eit195/Euv193 Jpeg as FloatMap:
var fn,B;
if(typeof JpgFile=='string'){
fn:=FindFile(JpgFile);
if (!fn) return Err('File "%s" not found',JpgFile);

//...

B:=LoadImage(fn);
if (!B) return Err('Failed to load file "%s"',Fn);
}else ...
return null;

var w:=B.Width, h:=B.Height, sz:=w/2048;

// original NASA color-map of 193 images:
var Sc0:=FindDataScale('Scale193_o.xml');
if (!Sc0) return null;

var F:=NFm().Assign(B,Sc0);
F.Info:={ ... };
//
// detect radius...
//...


// verify radius...
var Po:=GetSdoPos(F.Info.Time,{Width:w,Height:h});
if(Po){
// average difference of valid detected radius values
// vs SdoPos MagRadius is 1.00645 = 1+1/154.997

var RExp:=Po.MagRadius*1.008/1.199*w/1024*(1+1/155);
var RCalc:=F.Info.Radius;
if(RCalc && !IsInRange(RCalc,RExp*0.99,RExp*1.01)){
L('# Invalid radius %.3f, using %.3f from SdoPos',RCalc,RExp);
F.Info.Radius:=RExp;
}
}
//...

return F;
}

function Heq195(F,?Weight) {
// histogram equalization:
Weight:=Coalesce(Weight,0.2); // default Weight 0.2
var F2:=NFm(), sz:=Round(F.Width/2048);

F.HistEqualize(F2,{Min:0,Max:512,Step:2,Local:128*sz});
F.WeightMix(F2,Weight);
//...
return F;
}

function Eit195Alpha(F) {
// makes alpha mask for copying Eit195 (Euv193) onto white background:
var FMask:=F.Clone().Scale(1/255).Clip(0,1),fi:=F.Info;
FMask.MaskRange(72/255,1).FillEmpty(0).Power(3);
Rep(10,FMask.BoxCar(5)); // blur
var BMask:=NBm().Assign(FMask);
var sz:=F.Width/2048;
if(fi.Center)BMask.Circle(fi.Center,fi.Radius+1*sz,'#ffffff');
var Alpha:=(new ByteMap).Assign(BMask);
return Alpha;
}

function Eit195ow(F) {
// returns Bitmap from FloatMap, on white background...
var Sc1:=FindDataScale('Scale193_ow.xml');
if (!Sc1) return null;
var B1:=NBm().Assign(F,Sc1),B2:=B1;
// white background:
if(!Get('NoWhiteBg')){
B2:=NBm(F.Width,F.Height);
B2.Clear(0xffffffff);
var Alpha:=Eit195Alpha(F);
B1.WriteChannel(3,Alpha);
B1.DrawMode:=dmBlend;
B2.Draw(0,0,B1);
}
//...
return B2;
}

function TestHeqHc(JpgFile,?Weight) {
var F:=LoadEit195(JpgFile)||LoadImg(JpgFile);
if (!F) return null;
F:=Heq195(F,Weight);
var B:=Eit195ow(F);
return B;
}

The method to generate this composite from Fits files instead of Jpegs is similar...

...

(older first) older first
newest first
neither

Comments:

P.A.Semi #1
Comments may follow...
^ v