Program

Inicializace

DeleteFile["msgtemp.txt"];stream=OpenWrite["msgtemp.txt"];$Messages={stream};
SetSystemOptions["ParallelOptions"->{"MKLThreadNumber"->2$ProcessorCount,"ParallelThreadNumber"->2$ProcessorCount}];
SetOptions[EvaluationNotebook[],DockedCells->Cell[BoxData[ToBoxes[Button["Spusť program",FrontEndExecute[FrontEndToken["EvaluateNotebook"]],Method->"Queued"]]],"DockedCell"]];
scale=If[SystemInformation["Kernel","OperatingSystem"]=="Windows",(1/("Scale"/.SystemInformation["Devices","ConnectedDisplays"]//First)),1];

Texty

txt={"výstupní adresář","adresář, kam budou uložena zpracovaná data\nnejlépe Plocha",
"jasové snímky","jasové snímky z mono kamery,\nnebo v případě fotoaparátu\nkompozitní rgb snímky",
"červené snímky","snímky červeného filtru mono kamery","zelené snímky","snímky zeleného filtru mono kamery",
"modré snímky","snímky modrého filtru mono kamery","H-alfa snímky","snímky vodíkové čáry α úzkopásmového filtru mono kamery",
"OIII snímky","snímky dvakrát ionizovaného kyslíku úzkopásmového filtru mono kamery",
"SII snímky","snímky jednou ionizované síry úzkopásmového filtru mono kamery",
"dark snímek","temný kalibrační snímek kamery\nsnímek zakryté kamery se zcela stejným\nnastavením jako snímky oblohy",
"flat snímek L","jasové kalibrační snímky z mono kamery,\nnebo v případě fotoaparátu\nkompozitní rgb kalibrační snímky\nsnímky denní nebo soumračné oblohy\nbez hvězd, nebo bílé homogenní plochy",
"flat snímek R","červené kalibrační snímky z mono kamery denní, nebo soumračné\noblohy bez hvězd, nebo bílé homogenní plochy",
"flat snímek G","zelené kalibrační snímky z mono kamery denní, nebo soumračné\noblohy bez hvězd, nebo bílé homogenní plochy",
"flat snímek B","modré kalibrační snímky z mono kamery denní, nebo soumračné\noblohy bez hvězd, nebo bílé homogenní plochy",
"flat snímek Ha","H-α kalibrační snímky z mono kamery denní, nebo soumračné\noblohy bez hvězd, nebo bílé homogenní plochy",
"flat snímek OIII","OIII kalibrační snímky z mono kamery denní, nebo soumračné\n oblohy bez hvězd, nebo bílé homogenní plochy",
"flat snímek SII","SII kalibrační snímky z mono kamery denní, nebo soumračné\n oblohy bez hvězd, nebo bílé homogenní plochy",
"4k","snímek zmenšeny v násobku dvou\na oříznutý na 4096 bodů na šířku\npři zachování poměru stran",
"3k","snímek zmenšeny v násobku dvou\na oříznutý na 3072 bodů na šířku\npři zachování poměru stran",
"2k","snímek zmenšeny v násobku dvou\na oříznutý na 2048 bodů na šířku\npři zachování poměru stran",
"2k+","snímek zmenšeny v násobku dvou třetin\na oříznutý na 2048 bodů na šířku\npři zachování poměru stran",
"ořez:","vstup:","složené","série","typ kalibračních snímků\nuž složené tzv. mastery,\nnebo jednotlivé snímky\npokud je v okamžiku ukládání zvolena série\nuloží se mastery kalibračních snímků",
"📸","volba vstupu kompozitních rgb\nsnímků z fotoaparátu","L","volba vstupu jasových snímků\nz černobílé kamery",
"RGB","volba vstupu r g b snímků\nz černobílé kamery","HaOIII","volba vstupu H-α a OIII snímků\nz černobílé kamery",
" SII","volba vstupu SII snímků\nz černobílé kamery",
"digi flat","syntetické rovnání pozadí\npoužijte jen když i po kalibraci zbyly\nv obraze gradienty\n(kolečka od prachu neodstraní)",
"iterací","počet opakování digitálního rovnání pozadí\njeden nemusí být dostačující, dva, nebo tři stačí\npět je perfektní, deset je placebo",
"zoom:"," full ","1:1","zobrazení obrazu roztaženého tak,\naby vyplnil okno, nebo zobrazení\nv skutečné velikosti",
"slož snímky","spuštění procesu zarovnání a složení snímků\nkonec oznámí melodie",
"stretch:","míra intenzity expanzní křivky jasů",
"black:","hranice přechodu expanzní křivky v inverzní (inflexní bod)\npod touto hranicí budou data místo zesvětlování ztmavována,\nale díky plynulému ztmavování ne oříznuta",
"metoda:"," log ","asinh","logaritmický, nebo arcus sinus hyperbolický\nprůběh expanze jasů (stretch)",
"cmp","komprese světel",
"Done:","%  Unrotated:","  Included:","  Excluded:",
"ulož","uloží obraz do výstupního adresáře\nve formátu 32bit FIT, 16bit TIF a JPG","adresář s daty","plochý snímek","dark flaty:","flaty:"};

Parametry

cr=it=1;ori=done=True;rgb=l=hao=si=hdr=False;workDir=darkFile=lvl=0;dataDir={0,0,0,0,0,0,0};flatFile={1,1,1,1,1,1,1};
shift=150; angle=2;butSize=126*scale;p=3.5;c=0;z=1;sMin=1;sMax=6;bMin=-0.9;bMax=0.9;param={Method->{"ImageAlign",{"Keypoints","AKAZE"}},TransformationClass->"Rigid"};
final=Table[0,100];sc=150;
content={scale*1024,If[(-SystemInformation["Devices","ScreenInformation"][[1]][[1]][[2]][[2]]/.List->Subtract)>scale*946,scale*768,
					(-SystemInformation["Devices","ScreenInformation"][[1]][[1]][[2]][[2]]/.List->Subtract)-178-(scale-1)*32]};

I/O

wD=
	Function[
		Module[{input=SystemDialogInput["Directory",WindowTitle->txt[[1]]]},
			If[input===$Canceled,0,
				input
			]
		]
	];


dD=
	Function[
		Module[{input=SystemDialogInput["Directory",workDir,WindowTitle->txt[[82]]]},
			If[input===$Canceled,0,
				input
			]
		]
	];


dF=
	Function[{vst},
		If[vst==1,
			Module[{input=SystemDialogInput["FileOpen",workDir,WindowTitle->txt[[17]]]},
				If[input===$Canceled,0,
					impFit[input]
				]
			],
			Module[{files=FileNames[{"*.fits","*.tif","*.fit","*.tiff","*.raw","*.arw","*.crw","*.nef","*.nrw","*.dng"},{dD[]}],suma=0,n,out},
				at=AbsoluteTime[];err=0;count=1;cnt=Length[files];
				SetOptions[window,Enabled->False];done=False;
				Do[suma=suma+impFit[files[[n]]];count=n,{n,1,Length[files]}];
				beep[];
				SetOptions[window,Enabled->True];done=True;ClearAll[cnt];
				suma/Length[files]
			]
		]
	];

fF=
	Function[{vst},
		If[vst==1,
			Module[{input=SystemDialogInput["FileOpen",workDir,WindowTitle->txt[[83]]],flat},
				If[input===$Canceled,1,
					flat=impFit[input];(flat/(Max[flat]))
				]
			],
			Module[{dir1=workDir,dir2=workDir,darkFlat,suma=0,n,out,flat,files1,files2},
				DialogInput[{Column[{
					Row[{txt[[84]],FileNameSetter[Dynamic[dir1],"Directory"]}],
					Row[{txt[[85]],FileNameSetter[Dynamic[dir2],"Directory"]}],
					Button["ok",DialogReturn[{dir1,dir2}]]},Alignment->Right]		
				}];
				If[dir2==workDir,1,
					files1=FileNames[{"*.fits","*.tif","*.fit","*.tiff","*.raw","*.arw","*.crw","*.nef","*.nrw","*.dng"},{dir1}];
					files2=FileNames[{"*.fits","*.tif","*.fit","*.tiff","*.raw","*.arw","*.crw","*.nef","*.nrw","*.dng"},{dir2}];
					at=AbsoluteTime[];err=0;count=1;cnt=Length[files1]+Length[files2];
					darkFlat=
						If[dir1==workDir,0,
							SetOptions[window,Enabled->False];done=False;
							Do[suma=suma+impFit[files1[[n]]];count++,{n,1,Length[files1]}];
							suma/Length[files1]
						];
					SetOptions[window,Enabled->False];done=False;
					Do[suma=suma+calibratre[impFit[files2[[n]]],darkFlat,1];count++,{n,1,Length[files2]}];
					beep[];
					SetOptions[window,Enabled->True];done=True;ClearAll[cnt];
					flat=suma/Length[files2];(flat/(Max[flat]))
				]
			]
		]
	];

sV=
	Function[{out,vst},
		Export[FileNameJoin[{workDir,"final.fit"}],out,"BitDepth"->32];
		Export[FileNameJoin[{workDir,"final.tif"}],out,"BitDepth"->16,"ColorSpace"->"RGB"];
		Export[FileNameJoin[{workDir,"final.jpg"}],out,"JPEG","CompressionLevel"->0];
		If[vst==2,
			Export[FileNameJoin[{workDir,"master_dark.fit"}],darkFile,"BitDepth"->32];
			If[l&&!zr,Export[FileNameJoin[{workDir,"master_flat_light.fit"}],flatFile[[1]],"BitDepth"->32]];
			If[rgb&&!zr,Export[FileNameJoin[{workDir,"master_flat_red.fit"}],flatFile[[2]],"BitDepth"->32]];
			If[rgb&&!zr,Export[FileNameJoin[{workDir,"master_flat_green.fit"}],flatFile[[3]],"BitDepth"->32]];
			If[rgb&&!zr,Export[FileNameJoin[{workDir,"master_flat_blue.fit"}],flatFile[[4]],"BitDepth"->32]];
			If[hao&&!zr,Export[FileNameJoin[{workDir,"master_flat_H-alfa.fit"}],flatFile[[5]],"BitDepth"->32]];
			If[hao&&!zr,Export[FileNameJoin[{workDir,"master_flat_OIII.fit"}],flatFile[[6]],"BitDepth"->32]];
			If[hao&&si&&!zr,Export[FileNameJoin[{workDir,"master_flat_SII.fit"}],flatFile[[7]],"BitDepth"->32]];
			If[zr,Export[FileNameJoin[{workDir,"master_flat_composit.fit"}],flatFile[[1]],"BitDepth"->32]];
		]
	];

ButtonQ

vstupQ=Function[done];
jasQ=Function[(workDir!=0)&&(l||zr)&&done];
darkQ=Function[(workDir!=0)&&done];
flatQ=Function[(workDir!=0)&&(l||zr)&&done];
redQ=Function[(workDir!=0)&&rgb&&!zr&&done];
greenQ=Function[(workDir!=0)&&rgb&&!zr&&done];
blueQ=Function[(workDir!=0)&&rgb&&!zr&&done];
haQ=Function[(workDir!=0)&&hao&&!zr&&done];
oIIIQ=Function[(workDir!=0)&&hao&&!zr&&done];
sIIQ=Function[(workDir!=0)&&hao&&si&&!zr&&done];
redFQ=Function[(workDir!=0)&&rgb&&!zr&&done];
greenFQ=Function[(workDir!=0)&&rgb&&!zr&&done];
blueFQ=Function[(workDir!=0)&&rgb&&!zr&&done];
haFQ=Function[(workDir!=0)&&hao&&!zr&&done];
oIIIFQ=Function[(workDir!=0)&&hao&&!zr&&done];
sIIFQ=Function[(workDir!=0)&&hao&&si&&!zr&&done];
cropQ=Function[(workDir!=0)&&ImageQ[final[[lvl]]]&&done];
slozQ=
	Function[
		(workDir!=0)&&
		(
			If[l||zr,dataDir[[1]]!=0,True]&&
			If[rgb&&!zr,(dataDir[[2]]!=0)&&(dataDir[[3]]!=0)&&(dataDir[[4]]!=0),True]&&
			If[hao&&!zr,(dataDir[[5]]!=0)&&(dataDir[[6]]!=0),True]&&
			If[hao&&si&&!zr,dataDir[[7]]!=0,True]
		)&&done&&(zr||l||rgb||hao)
	];
vyrovQ=Function[(workDir!=0)&&ImageQ[final[[lvl]]]&&done];
ulozQ=Function[(workDir!=0)&&ImageQ[final[[lvl]]]&&done];

Funkce

beep=
	Function[
		EmitSound[Sound[{SoundNote["A"],SoundNote["B"],SoundNote["G"],SoundNote["G3"],SoundNote["D"]},1]]
	];

formatTiming=
	StringJoin[{If[#>=100,ToString@#,
		IntegerString[#,10,2]]&@Floor[#/3600],"h ",
		IntegerString[Floor[Mod[#,3600]/60],10,2],"min ",
		IntegerString[Mod[#,60],10,2],"s"}&@Round[#]]&;

impFit=
	Function[{file},
		Module[{im=Import[file],of,ff},
			of=If[ImageQ[im],im,im[[1]]];
			ff=If[Length[of]!=0,ColorCombine[of,"rgb"],of];
			If[(ImageChannels[ff]==1)&&zr,ImageDemosaic[ff,"RGGB"],ff]
		]
	];

croop=
	Function[{img},
		Module[{w,h,d},
			{w,h}=ImageDimensions[img];
			d=1024Floor[(w/1024)];
			ImageCrop[img,{d,Floor[d (h/w)]}]
		]
	];

histoTrans=
	Function[{img,m},
		Module[{
			medi=FindThreshold[img,Method->{"BlackFraction", m}],
			blk=FindThreshold[img,Method->{"BlackFraction", 0.01}],
			wht=FindThreshold[img,Method->{"BlackFraction", 0.9997}]},
			ImageClip[InterpolatingPolynomial[{{blk,0},{medi,1}},img]]
			ImageClip[InterpolatingPolynomial[{{wht,1},{1,1/2}},img]]
		]
	];

imRaMin=
	Function[{img,n},
		RankedMin[Flatten[ImageData[img]],n]
	];

imRaMax=
	Function[{img,n},
		RankedMax[Flatten[ImageData[img]],n]
	];

saturMax=
	Function[{img,n},
		Module[{h,s,b,cnt=Floor[n*Length[Flatten[ImageData[img]]]/100]},
			{h,s,b}=ColorSeparate[ColorConvert[img,"HSB"]];
			ColorConvert[ColorCombine[{h,Clip[s/Max[{imRaMax[s,cnt],-imRaMin[s,cnt]}],{-1,1}],b},"HSB"],"RGB"]
		]
	];

stretch=
	Function[{img,power,c,s,hdr},
		Module[{me=FindThreshold[img,Method->{"BlackFraction", 0.001}]*(1+c),im,in,lp,out},
			im=((ImageClip[img-me])/(1-me));
			in=((ImageClip[me-img])/me);
			out=
				If[s==1,
					lp=Log[power];(1-me) (1+((Log[im+((1-im)/power)])/lp))-(me/2) (1+((Log[in+((1-in)/power)])/lp))-((me in)/2),
					lp=ArcSinh[power];(1-me)(((ArcSinh[im*power])/lp))-(me/2)(((ArcSinh[in*power])/lp))-((me in)/2)
				]+me;
			If[hdr,Sin[π out/2]^1.2,out]
				
		]
	];

normal=
	Function[{img},
		Module[{min=imRaMin[img,500],in},
			in=img-min;
			(in/(imRaMax[in,500]))
		]
	];

calibratre=
	Function[{img,dark,flat},
		((img-dark)/flat)
	];

bin=
	Function[{img,bf},
		Binarize[img,Method->{"BlackFraction", bf}]
	];

gaussianBlur=
	Function[{img,rad},
		Module[{r=Floor[Clip[rad,{1,2047}]]},
			ImageConvolve[img,Clip[GaussianMatrix[r]-GaussianMatrix[r][[1,r]],{0,Infinity}]]
		]
	];

exAngOf=
	Function[{trMat},
		Module[{e,t,tm,qr},
			{e,t}=trMat;
			tm=TransformationMatrix[t];
			qr=QRDecomposition[tm[[;;-2, ;;-2]]];
			{tm[[1;;2,-1]],Abs[180ArcTan@@First[DiagonalMatrix[Sign[Diagonal[qr[[2]]]]].qr[[1]]]/π]}
		]
	];

starNo=
	Function[{img,x},
		Length[ComponentMeasurements[Binarize[img,Method->{"BlackFraction", x}],"Count"]]
	];

bfTres=
	Function[{img,no},
		Module[{x},
			Fit[Map[{starNo[img,0.999+0.0001#],0.999+0.0001#}&,Range[9]], {1,x,x^2,x^3,x^4},x]/.x->no
		]
	];

Metody

colorize=
	Function[{lL,rR,gG,bB,sm},
		Module[{cR,cG,cB,mR,mG,mB,h,s,b},
			{cR,cG,cB}={rR,gG,bB};
			Do[
				Parallelize[
					{cR,cG,cB}=
						{
							BrightnessEqualize[cR,{"Global",n},PerformanceGoal->"Speed",Masking->1-Dilation[Erosion[Binarize[cR,Method->{"BlackFraction", 0.996-0.001n}],1],1]],
							BrightnessEqualize[cG,{"Global",n},PerformanceGoal->"Speed",Masking->1-Dilation[Erosion[Binarize[cG,Method->{"BlackFraction", 0.996-0.001n}],1],1]],
							BrightnessEqualize[cB,{"Global",n},PerformanceGoal->"Speed",Masking->1-Dilation[Erosion[Binarize[cB,Method->{"BlackFraction", 0.996-0.001n}],1],1]]
					},ProgressReporting->False
				],{n,1,6}
			];
			Parallelize[
				{mR,mG,mB}={FindThreshold[cR,Method->{"BlackFraction", 0.1}],FindThreshold[cG,Method->{"BlackFraction", 0.1}],FindThreshold[cB,Method->{"BlackFraction", 0.1}]};
				{cR,cG,cB}={(cR-mR)/(Max[cR]-mR),(cG-mG)/(Max[cG]-mG),(cB-mB)/(Max[cB]-mB)},ProgressReporting->False
			];
			{h,s,b}=ColorSeparate[normal[ColorCombine[{cR,cG,cB},"RGB"]],"HSB"];
			saturMax[ColorConvert[ColorCombine[Join[{lL},ColorSeparate[ColorCombine[Join[{h,s*histoTrans[b,2/3]},{lL}],"HSB"],"LUV"][[2;;3]]],"LUV"],"RGB"],sm]
		]
	];

remBad=
	Function[{img},
		Module[{im=normal[img]},
			Inpaint[img,Binarize[ImageClip[im-1,{0,1}]-ImageClip[im,{-1,0}],0],Method->"Diffusion"]
		]
	];

mask=
	Function[{img},
		Module[{fl=normal[img-gaussianBlur[Erosion[Dilation[img,1],Min[ImageDimensions[img]]/8],Min[ImageDimensions[img]]/2]]},
			Dilation[Erosion[
				Binarize[BrightnessEqualize[fl,{"Global",4},PerformanceGoal->"Speed",Masking->1-
					Dilation[Erosion[
						Binarize[BrightnessEqualize[fl,{"Global",1},PerformanceGoal->"Speed"],Method->{"BlackFraction", 0.9}],
					1],2]],
				Method->{"BlackFraction", 2/3}],
			1],3]
		]
	];

oneFlat=
	Function[{img,msk,g},
		Module[{flt},
			flt=BrightnessEqualize[img,{"Global",g},PerformanceGoal->"Speed",Masking->msk];
			If[ImageQ[flt],flt,oneFlat[img,msk,g-1]]
		]
	];

digitalFlat =
	Function[{img,level,iter},
		If[0<iter,
			Module[{gray=ColorSeparate[img,"HSB"][[3]],flt},
				flt=gray/oneFlat[gray,1-mask[gray],6];
				digitalFlat[img/flt,level,iter-1]
			],
			img
		]
	];

trMat=
	Function[{imga,img2,bf,pok},
		Module[{imgb=bin[img2,bf],ep,tp,e,t},
			{ep,tp}=If[ori,FindGeometricTransform[imga,imgb,param],FindGeometricTransform[imga,ImageRotate[imgb,π],param]];
			{e,t}=If[ori,{ep,tp},{ep,Composition[tp,RotationTransform[π,ImageDimensions[imgb]/2]]}];
			If[(pok<2)&&(((t/.TransformationFunction->List)=={IdentityMatrix[3]})||(ori!=(exAngOf[{e,t}][[2]]<angle))),
				ori=!ori; trMat[imga,imgb,bf,pok+1],
				If[pok<2,{e,t},{0,0}]
			]
		]
	];

imageAlign=
	Function[{img,trMat},
		Module[{dx,dy,α,w,h,er,tr},
			{er,tr}=trMat;
			{{dx,dy},α}=If[er!=0,exAngOf[trMat],{{0,0},90}];
			{w,h}=ImageDimensions[img];
			If[er≠0&&((-shift<dx<shift&&-shift<dy<shift&&α<angle)||(w-shift<dx<w+shift&&h-shift<dy<h+shift&&α>180-angle)),
					count++;ImagePerspectiveTransformation[img,tr,Resampling->{"Spline",9},DataRange->Full],
					err++;Nothing
			]
		]
	];

stack=
	Function[{files,flat},
		Module[{first=remBad[calibratre[impFit[files[[1]]],darkFile,flat]],birst,bf,suma,n},
			bf=bfTres[first,sc];
			birst=bin[first,bf];
			suma=first;
			Do[suma=suma+Module[
								{img=remBad[calibratre[impFit[files[[n]]],darkFile,flat]]},
								imageAlign[img,trMat[birst,img,bf,0]]
							],
				{n,2,Length[files]}
			];
			suma
		]
	];

Akce

mr=
	Function[
		SetOptions[window,Enabled->False];done=False;
		Module[{Q={l||zr,rgb&&!zr,rgb&&!zr,rgb&&!zr,hao&&!zr,hao&&!zr,hao&&si&&!zr},
				vzNo=Min[{If[l||zr,1,Nothing],If[rgb,3,Nothing],If[hao,5,Nothing]}],
				files,master,imDim,bf,birst,align,(*allMaster,aC,*)return},
			files=Map[If[Q[[#]],FileNames[{"*.fits","*.tif","*.fit","*.tiff","*.raw","*.arw","*.crw","*.nef","*.nrw","*.dng"},{dataDir[[#]]}],0]&,Range[7]];
			cnt=Map[If[Q[[#]],Length[files[[#]]],0]&,Range[7]]/.List->Plus;
			count=1;err=0;
			master=Map[If[Q[[#]],stack[files[[#]],flatFile[[#]]],0]&,Range[7]];
			imDim=ImageDimensions[master[[vzNo]]];
			bf=bfTres[master[[vzNo]],sc];
			birst=bin[master[[vzNo]],bf];
			align=Map[If[Q[[#]],If[vzNo==#,master[[#]],imageAlign[master[[#]],trMat[birst,master[[#]],bf,0]]],0]&,Range[7]];
			aC=Map[If[Q[[#]],ImageCrop[align[[#]],imDim-2{4 shift/3,shift}],0]&,Range[7]];
			allMaster=aC/.List->Plus;
			return=normal[
						Which[
							zr,colorize[normal[ColorConvert[normal[allMaster],"Grayscale"]],ColorSeparate[allMaster,"R"],ColorSeparate[allMaster,"G"],ColorSeparate[allMaster,"B"],0.01],
							rgb&&hao&&si&&l,colorize[normal[allMaster],aC[[7]]+aC[[5]]+aC[[2]],aC[[5]]+aC[[6]]+aC[[3]],aC[[6]]+aC[[4]],0.01],
							rgb&&hao&&si,colorize[normal[allMaster],aC[[7]]+aC[[5]]+aC[[2]],aC[[5]]+aC[[6]]+aC[[3]],aC[[6]]+aC[[4]],0.01],
							rgb&&hao&&l,colorize[normal[allMaster],aC[[5]]+aC[[2]],aC[[6]]+aC[[3]],aC[[6]]+aC[[4]],0.01],
							rgb&&hao,colorize[normal[allMaster],aC[[5]]+aC[[2]],aC[[6]]+aC[[3]],aC[[6]]+aC[[4]],0.01],
							hao&&si&&l,colorize[normal[allMaster],aC[[7]]+aC[[5]],aC[[5]]+aC[[6]],aC[[6]],0.01],
							hao&&si,colorize[normal[allMaster],aC[[7]]+aC[[5]],aC[[5]]+aC[[6]],aC[[6]],0.01],
							rgb&&l,colorize[normal[allMaster],aC[[2]],aC[[3]],aC[[4]],0.01],
							rgb,colorize[normal[allMaster],aC[[2]],aC[[3]],aC[[4]],0.01],
							hao&&l,colorize[normal[allMaster],aC[[5]],aC[[6]],aC[[6]],0.01],
							hao,colorize[normal[allMaster],aC[[5]],aC[[6]],aC[[6]],0.01],
							l,normal[allMaster]
						]
					];
			beep[];
			SetOptions[window,Enabled->True];done=True;ClearAll[cnt];
			return
		]
	];

fl=
	Function[{final,flatIter},
		SetOptions[window,Enabled->False];done=False;
		Module[{return=normal[digitalFlat[final,1,flatIter]]},
			beep[];
			SetOptions[window,Enabled->True];done=True;
			return
		]
	];

crp=
	Function[{cr},
		Module[{w,h},
			{w,h}=ImageDimensions[final[[lvl]]];
			Which[
				cr==1,If[w>4096,final[[++lvl]]=croop[ImageResize[final[[lvl]],Scaled[(1/(Floor[(w/4096)]))],Resampling->"Nearest"]]],
				cr==2,If[w>3072,final[[++lvl]]=croop[ImageResize[final[[lvl]],Scaled[(1/(Floor[(w/3072)]))],Resampling->"Nearest"]]],
				cr==3,If[w>2048,final[[++lvl]]=croop[ImageResize[final[[lvl]],Scaled[(1/(Floor[(w/2048)]))],Resampling->"Nearest"]]],
				cr==4,If[w>3072,final[[++lvl]]=croop[ImageResize[final[[lvl]],Scaled[(2/(3Floor[(w/3072)]))],Resampling->"Nearest"]]]
			];
			final[[lvl+1]]=0;
		]
	];

Applikace

window=CreateDialog[{
	Grid[{{
		Grid[{
				{
					Tooltip[Button[Style[txt[[1]],FontSize->scale*13,FontFamily->"Arial"],workDir=wD[],Method->"Queued",Enabled->Dynamic[vstupQ[]],Background->White,ImageSize->butSize],txt[[2]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[3]],FontSize->scale*13,FontFamily->"Arial"],dataDir[[1]]=dD[],Method->"Queued",Enabled->Dynamic[jasQ[]],Background->White,ImageSize->butSize],txt[[4]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[5]],FontSize->scale*13,FontFamily->"Arial"],dataDir[[2]]=dD[],Method->"Queued",Enabled->Dynamic[redQ[]],Background->LightRed,ImageSize->butSize],txt[[6]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[7]],FontSize->scale*13,FontFamily->"Arial"],dataDir[[3]]=dD[],Method->"Queued",Enabled->Dynamic[greenQ[]],Background->LightGreen,ImageSize->butSize],txt[[8]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[9]],FontSize->scale*13,FontFamily->"Arial"],dataDir[[4]]=dD[],Method->"Queued",Enabled->Dynamic[blueQ[]],Background->LightBlue,ImageSize->butSize],txt[[10]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[11]],FontSize->scale*13,FontFamily->"Arial"],dataDir[[5]]=dD[],Method->"Queued",Enabled->Dynamic[haQ[]],Background->Darker[LightRed],ImageSize->butSize],txt[[12]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[13]],FontSize->scale*13,FontFamily->"Arial"],dataDir[[6]]=dD[],Method->"Queued",Enabled->Dynamic[oIIIQ[]],Background->LightCyan,ImageSize->butSize],txt[[14]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[15]],FontSize->scale*13,FontFamily->"Arial"],dataDir[[7]]=dD[],Method->"Queued",Enabled->Dynamic[sIIQ[]],Background->LightYellow,ImageSize->butSize],txt[[16]],TooltipDelay->0.6]
				},
				{
					Tooltip[Button[Style[txt[[17]],FontSize->scale*13,FontFamily->"Arial"],darkFile=dF[vst],Method->"Queued",Enabled->Dynamic[darkQ[]],Background->Gray,ImageSize->butSize],txt[[18]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[19]],FontSize->scale*13,FontFamily->"Arial"],flatFile[[1]]=fF[vst],Method->"Queued",Enabled->Dynamic[flatQ[]],Background->LightGray,ImageSize->butSize],txt[[20]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[21]],FontSize->scale*13,FontFamily->"Arial"],flatFile[[2]]=fF[vst],Method->"Queued",Enabled->Dynamic[redFQ[]],Background->Darker[LightRed],ImageSize->butSize],txt[[22]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[23]],FontSize->scale*13,FontFamily->"Arial"],flatFile[[3]]=fF[vst],Method->"Queued",Enabled->Dynamic[greenFQ[]],Background->Darker[LightGreen],ImageSize->butSize],txt[[24]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[25]],FontSize->scale*13,FontFamily->"Arial"],flatFile[[4]]=fF[vst],Method->"Queued",Enabled->Dynamic[blueFQ[]],Background->Darker[LightBlue],ImageSize->butSize],txt[[26]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[27]],FontSize->scale*13,FontFamily->"Arial"],flatFile[[5]]=fF[vst],Method->"Queued",Enabled->Dynamic[haFQ[]],Background->Darker[Darker[LightRed]],ImageSize->butSize],txt[[28]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[29]],FontSize->scale*13,FontFamily->"Arial"],flatFile[[6]]=fF[vst],Method->"Queued",Enabled->Dynamic[oIIIFQ[]],Background->Darker[LightCyan],ImageSize->butSize],txt[[30]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[31]],FontSize->scale*13,FontFamily->"Arial"],flatFile[[7]]=fF[vst],Method->"Queued",Enabled->Dynamic[sIIFQ[]],Background->Darker[LightYellow],ImageSize->butSize],txt[[32]],TooltipDelay->0.6]
				},
				{
					Tooltip[Control[{{vst,1,Style[txt[[42]],FontSize->scale*10,FontFamily->"Arial"]},{1->Style[txt[[43]],FontSize->scale*10,FontFamily->"Arial"],2->Style[txt[[44]],FontSize->scale*10,FontFamily->"Arial"]}}],txt[[45]],TooltipDelay->0.6],
					Row[{Style[txt[[41]],FontSize->scale*10,FontFamily->"Arial"],
						Button[Tooltip[Style[txt[[33]],FontSize->scale*10,FontFamily->"Arial"],txt[[34]],TooltipDelay->0.6],crp[1],Background->LightBlue,ImageSize->{scale*25,scale*25}],
						Button[Tooltip[Style[txt[[35]],FontSize->scale*10,FontFamily->"Arial"],txt[[36]],TooltipDelay->0.6],crp[2],Background->LightBlue,ImageSize->{scale*25,scale*25}],
						Button[Tooltip[Style[txt[[37]],FontSize->scale*10,FontFamily->"Arial"],txt[[38]],TooltipDelay->0.6],crp[3],Background->LightBlue,ImageSize->{scale*25,scale*25}],
						Button[Tooltip[Style[txt[[39]],FontSize->scale*10,FontFamily->"Arial"],txt[[40]],TooltipDelay->0.6],crp[4],Background->LightBlue,ImageSize->{scale*27,scale*25}]
					}],
					Row[{
						Tooltip[Row[{Style[txt[[46]],FontSize->11],Checkbox[Dynamic[zr]]},Frame->True,FrameMargins->3,FrameStyle->Gray],txt[[47]],TooltipDelay->0.6],Spacer[3],
						Tooltip[Row[{Style[txt[[48]],FontSize->scale*9,FontFamily->"Arial"],Checkbox[Dynamic[l]]},Frame->True,FrameMargins->3,FrameStyle->Gray],txt[[49]],TooltipDelay->0.6],Spacer[3],
						Tooltip[Row[{Style[txt[[50]],FontSize->scale*9,FontFamily->"Arial"],Checkbox[Dynamic[rgb]]},Frame->True,FrameMargins->3,FrameStyle->Gray],txt[[51]],TooltipDelay->0.6]
					}],
					Row[{
						Tooltip[Row[{Style[txt[[52]],FontSize->scale*9,FontFamily->"Arial"],Checkbox[Dynamic[hao]]},Frame->True,FrameMargins->3,FrameStyle->Gray],txt[[53]],TooltipDelay->0.6],Spacer[3],
						Tooltip[Row[{Style[txt[[54]],FontSize->scale*9,FontFamily->"Arial"],Checkbox[Dynamic[si]]},Frame->True,FrameMargins->3,FrameStyle->Gray],txt[[55]],TooltipDelay->0.6]
					}],
					Tooltip[Button[Style[txt[[56]],FontSize->scale*13,FontFamily->"Arial"],final[[lvl+2]]=0;final[[++lvl]]=fl[final[[lvl]],it],Method->"Queued",Enabled->Dynamic[vyrovQ[]],Background->White,ImageSize->butSize],txt[[57]],TooltipDelay->0.6],
					Row[{
						Tooltip[Row[{Control[{it,Range[10]}],Style[txt[[58]],FontSize->scale*10,FontFamily->"Arial"]}],txt[[59]],TooltipDelay->0.6],
						Button[Style["↩︎",FontSize->12],If[lvl>1,--lvl],Background->LightBlue,ImageSize->{scale*25,scale*25}],
						Button[Style["↪︎",FontSize->12],If[ImageQ[final[[lvl+1]]],++lvl],Background->LightBlue,ImageSize->{scale*25,scale*25}]
					}],
					Tooltip[Control[{{z,1,Style[txt[[60]],FontSize->scale*10,FontFamily->"Arial"]},{1->Style[txt[[61]],FontSize->scale*10,FontFamily->"Arial"],2->Style[txt[[62]],FontSize->scale*10,FontFamily->"Arial"]}}],txt[[63]],TooltipDelay->0.6],
					Tooltip[Button[Style[txt[[64]],FontSize->scale*13,FontFamily->"Arial"],at=AbsoluteTime[];final[[++lvl]]=mr[],Method->"Queued",Enabled->Dynamic[slozQ[]],Background->White,ImageSize->butSize],txt[[65]],TooltipDelay->0.6]
				}
			},Alignment->{Center,Center,{{3,3}->{Right,Center},{3,4}->{Left,Center},{3,6}->{Left,Center}}}]
		},
		{
			Manipulate[If[ImageQ[final[[lvl]]],Deploy[Image[out= stretch[final[[lvl]],(10^p),c,s,hdr],Magnification->If[z==1,Max[(content/(ImageDimensions[final[[lvl]]]))],scale*1]]],Spacer[1]],
				Row[{Row[{
					Tooltip[Row[{
						Style[txt[[66]],FontSize->scale*10,FontFamily->"Arial"],
						Button["←",If[p>sMin,p=p-0.1],ImageSize->{scale*16,scale*16},Appearance->"Palette",Alignment->Bottom],
						Slider[Dynamic[p],{sMin,sMax,0.1},ImageSize->scale*130],
						Button["→",If[p<sMax,p=p+0.1],ImageSize->{scale*16,scale*16},Appearance->"Palette",Alignment->Bottom],
						InputField[Dynamic[p,(If[#<sMin,p=sMin,If[#>sMax,p=sMax,p=#]]&)],ImageSize->scale*25,ContinuousAction->True]
					}],txt[[67]],TooltipDelay->0.6],Spacer[5],
					Tooltip[Row[{
						Style[txt[[68]],FontSize->scale*10,FontFamily->"Arial"],
						Button["←",If[c>bMin,c=Chop[c-0.1]],ImageSize->{scale*16,scale*16},Appearance->"Palette",Alignment->Bottom],
						Slider[Dynamic[c],{bMin,bMax,0.1},ImageSize->scale*130],
						Button["→",If[c<bMax,c=Chop[c+0.1]],ImageSize->{scale*16,scale*16},Appearance->"Palette",Alignment->Bottom],
						InputField[Dynamic[c,(If[#<bMin,c=bMin,If[#>bMax,c=bMax,c=#]]&)],ImageSize->scale*25,ContinuousAction->True]
					}],txt[[69]],TooltipDelay->0.6],Spacer[5],
					Tooltip[Control[{{s,1,Style[txt[[70]],FontSize->scale*10,FontFamily->"Arial"]},{1->Style[txt[[71]],FontSize->scale*10,FontFamily->"Arial"],2->Style[txt[[72]],FontSize->scale*10,FontFamily->"Arial"]}}],txt[[73]],TooltipDelay->0.6],
					Spacer[5],Style[txt[[74]],FontSize->scale*9,FontFamily->"Arial"],Tooltip[Checkbox[Dynamic[hdr]],txt[[75]],TooltipDelay->0.6]},Frame->True,FrameStyle->Gray,FrameMargins->1],Spacer[10],
					Style[txt[[76]]Dynamic[If[NumberQ[cnt],""<>IntegerString[Floor[100count/cnt],10,3]<>
					txt[[77]]<>ToString[ori]<>txt[[78]]<>IntegerString[count,10,4]<>
					txt[[79]]<>IntegerString[err,10,4]<>"  "<>
					If[!done,formatTiming[Floor[(((AbsoluteTime[]-at) cnt)/(count+err))-(AbsoluteTime[]-at)]],
						"00h 00min 00s"
					],""]],FontSize->scale*10,FontFamily->"Arial"],Spacer[4],Dynamic[Tooltip[Button[Style[txt[[80]],FontSize->scale*13,FontFamily->"Arial"],sV[out,vst],Method->"Queued",Enabled->ulozQ[]],txt[[81]],TooltipDelay->0.6]]
					}],ContentSize ->content,ControlPlacement->Bottom,FrameMargins->None,AppearanceElements->None
				]
		}},Alignment->{Center,Center}]
		},WindowTitle->"AstroBot (Beta 1.26)",Background->Lighter[Gray, 0.25]
	];