I have a 1443x998 picture of the stars (taken w/ a 35mm camera and then scanned) with the following stars at the following pixel locations:
Altair x=782, y=532 [19h50m46.9990s RA, +08 52'05.959'' DEC]
Sualocin, x=311, y=146 [20h 39m 38.287s +15 54'43.49'' DEC]
Denebokab, x=1023, y=815 [19h25m29.9005s +03 06' 53.191'' DEC]
What mathematical function converts pixel location to RA/DEC and vice versa? Notes:
Bright stars are blobs in the picture; the coordinates above are roughly the center of the blob, but may be off by +-2 pixels.
I know I can rotate the celestial sphere so that the center of my picture has polar coordinates 0,0. So the real question is "how to find this rotation" (but see next point).
If elevation/azimuth were linear in pictures, this would be easy(er), but they're not: Measuring angular distance with photographs
I can provide pixel locations of more stars if that helps. I believe 3 should be sufficient, but I could be wrong.
I tried to choose 3 stars that were "spread out" across the picture (because I think that reduces error, not sure), but am not sure I succeeded.
I'm doing this for several pictures and would like a general method.
Doing this will help me identify fainter stars/Messier-objects/etc in the picture.
I'm sure lots of astrophotographers want to do this, but haven't found any existing software that does this.
EDIT: Thanks, whuber! The gnomonic projection is what I was missing. I'd already done this assuming a linear transformation:
(* convert RA/DEC to xyz coords on celestial psuedo-sphere of radius 1 *)
radecxyz[ra_,dec_] =
{Cos[ra/12*Pi]*Cos[dec/180*Pi],Sin[ra/12*Pi]*Cos[dec/180*Pi],Sin[dec/180*Pi]};
(* I no longer have any idea how this works *)
astrosolve[x_,y_,z_,xwid_,ywid_] := Module[{a,m,ans,nullans},
m=Array[a,{2,3}];
temp=Solve[{
m.radecxyz[x[[1]],x[[2]]]=={x[[3]]-xwid/2,x[[4]]-ywid/2},
m.radecxyz[y[[1]],y[[2]]]=={y[[3]]-xwid/2,y[[4]]-ywid/2},
m.radecxyz[z[[1]],z[[2]]]=={z[[3]]-xwid/2,z[[4]]-ywid/2}
}];
ans = m /. Flatten[temp];
nullans=Flatten[NullSpace[ans]];
If[nullans.radecxyz[x[[1]],x[[2]]]<0,nullans=-nullans];
Return[{ans,nullans}];
];
where x, y, and z were each 4-element lists consisting of a stars RA, declination, x-coordinate on picture, and y-coordinate on picture. xwid and ywid are the width and height of the picture. In this case:
astrosolve[
{19.8463886110, 8.8683219443, 782, 532},
{20.6606352777, 15.9120805555, 311, 146},
{19.4249723610, 3.1147752777, 1023, 815},
1443, 998]
{
{{-2250.51, -1182.52, 385.689}, {-166.12, -543.746, -2376.73}},
{0.480698, -0.861509, 0.163497}
}
Now, referring to "{-2250.51, -1182.52, 385.689}" as $frow, "{-166.12, -543.746, -2376.73}" as $srow, and "{0.480698, -0.861509, 0.163497}" as $null, this PHP subroutine translates RA/DEC to xy coordinates:
# radecxy(ra,dec): converts ra/dec to x,y using a quasi-linear transformation
function radecxy($ra,$dec) {
global $null,$frow,$srow,$xwid,$ywid;
list($x,$y,$z)=array(cos($dec)*cos($ra),cos($dec)*sin($ra),sin($dec));
$dotprod=$null[0]*$x+$null[1]*$y+$null[2]*$z;
if ($dotprod<0) {return(array(-1,-1));}
list($fx,$fy) = array($frow[0]*$x+$frow[1]*$y+$frow[2]*$z,$srow[0]*$x+$srow[1]*$y+$srow[2]*$z);
$fx+=$xwid/2;
$fy+=$ywid/2;
if ($fx<0 || $fy<0 || $fx>$xwid || $fy>$ywid) {
return(array(-1,-1));
} else {
return(array($fx,$fy));
}
}
Sadly, I no longer have any idea why this works, but using it + adding known star positions yields tolerable results (use "view image" to see it full size):
However, as you can see, the results aren't perfect, convincing me that a linear transformation wasn't the right answer. I think gnomonic might be the grail I was seeking.