<p>Because you cut the image and rotated it, the old reference is no longer there.</p>
<p>Try this and it works perfectly for me:</p>
<p>After fixing the cutout center on original image <code>center = wcs.all_world2pix(RA, Dec, 0)</code> and cutout size <code>size=(size_x,size_y)</code> of your cutout2D image, please update not only the WCS matrix elements in the new WCS but also the reference pixels <code>CRPIX1 = size_x/2</code>, <code>CRPIX2 = size_y/2</code> and positions <code>CRVAL1 = RA</code>, <code>CRVAL2 = DEC</code>.</p>
<p>Setting <code>reshape=False</code> in <code>scipy.ndimage.rotate</code> is important because you don't want the center reference pixel in the cutout image changes to other pixel place.</p>
<p>And please take care about the sign of renewed WCS matrix elements, although it is just the orientation and it depends on you.</p>

CC BY-SA 4.0
2023-03-12T02:07:21.683Z
2023-03-12T02:54:22.230Z
2023-03-12T02:54:22.230Z
Jerry Zhang
<p>I'm producing images from FITS files, But most of my images aren't aligned to the celestial north.</p>
<p>I would expect there to be a simple library, or even an astropy command to make the alignment of the image and axes for me, but after much research I didn't find much.</p>
<p>at the moment I am plotting the image using Cutout2D, and reading the wcs info from the header. skipping some lines my code looks like this:</p>
<pre><code>position = SkyCoord(ra=ra, dec=dec, frame='fk5', unit='deg')  # Object's position
wcs = WCS(header)
center = wcs.all_world2pix(position.ra, position.dec, 0)  # Put object at center
cutout = Cutout2D(image_data, center, size, wcs=wcs)
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=wcs)  # Change axes to WCS
ra = ax.coords[0]
dec = ax.coords[1]
ra.set_ticks(spacing=4. * u.arcsec)
dec.set_ticks(spacing=4. * u.arcsec)
plt.imshow(cutout.data, cmap='gray', norm=norm_linear, origin='lower')
</code></pre>
<p>I get images like this:</p>
<p><a href="https://i.sstatic.net/6mpc0.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/6mpc0.jpg" alt="" /></a></p>
<p>as you can see the grid lines of the axes aren't aligned.</p>
<p>The best I could achieve is rotating the image itself (using 'orientat' from the header which tells me in degrees the image orientation), and changing the header itself with some piece of code I found (but not sure is working properly):</p>
<pre><code>position = SkyCoord(ra=ra, dec=dec, frame='fk5', unit='deg')  # Object's position
orientat_deg = header['ORIENTAT']  # Get image orientation
h1 = header.copy()  # Copy of the original header
h1.update(
    cd1_1=-np.hypot(header[&quot;CD1_1&quot;], header[&quot;CD1_2&quot;]),
    cd1_2=0.0,
    cd2_1=0.0,
    cd2_2=np.hypot(header[&quot;CD2_1&quot;], header[&quot;CD2_2&quot;]),
    orientat=0.0)  # Update wcs to fit aligned wcs
wcs_rotate = WCS(h1)
center = wcs.all_world2pix(position.ra, position.dec, 0)  # Put object at center
cutout = Cutout2D(image_data, center, size, wcs=wcs_rotate)
rotated_img = ndimage.rotate(cutout.data, -orientat_deg, reshape=False)  # Create rotated image
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=wcs_rotate)  # Change axes to fixed wcs
ra = ax.coords[0]
dec = ax.coords[1]
ra.set_ticks(spacing=4. * u.arcsec)
dec.set_ticks(spacing=4. * u.arcsec)
plt.imshow(rotated_img, cmap='gray', norm=norm_linear, origin='lower')  # Plot rotated image with rotated axes
</code></pre>
<p>the image I get:</p>
<p><a href="https://i.sstatic.net/lfj7O.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/lfj7O.jpg" alt="" /></a></p>
<p>it would seem this messy piece of code works, the only problem is that the real coordinates for this object are: Longitude 00h09m11.577s, Latitude -00d36m54.73s (object's name SDSS J000911.57-003654.7), which isn't quite the coordinates presented on my axes.</p>
<p>I hope someone has a solution, Thank you.</p>

CC BY-SA 4.0
2022-03-16T20:54:02.360Z
Not a proper answer but maybe [reproject](https://reproject.readthedocs.io/en/stable/) might do what you want ? However your original image isn't showing the object near the correct coordinates either. What is the origin of the image and its WCS ? Can you display the image in an image viewer such as ds9 and see if the coordinates for the object are correct there (indicating an Astropy/plotting issue) or not (indicating an issue with the WCS fit in the original FITS image) ?
astrosnapper
CC BY-SA 4.0
2022-03-16T21:11:38.213Z
reproject (as does astroalign) seem to be more about aligning 2 different images to each other, rather than aligning one image north. I might be wrong, but I just couldn't find something that works for what I need (which I would expect is a very basic property in astro, so why is it so hard to find).

The first image shouldn't display the correct coordinates, since the grid isn't aligned at all (at least I think so), displaying the image in ds9 gives the correct coordinates.
The images are from HST, the wcs is from the header of the fits file.
Kipod23
CC BY-SA 4.0
2022-09-02T04:26:07.710Z
I installed montage and montage-wrapper as suggested in one of astropy issues in github and followed this link (also suggested in that issue)
https://stackoverflow.com/a/51967697/2527220
and it worked for me.
Lekha
<image-processing><alignment><fits-header>
align an image to celestial North
Kipod23
# align an image to celestial North

(Asked by: username_0 on 2022-03-16)

I'm producing images from FITS files, But most of my images aren't aligned to the celestial north.
I would expect there to be a simple library, or even an astropy command to make the alignment of the image and axes for me, but after much research I didn't find much.
at the moment I am plotting the image using Cutout2D, and reading the wcs info from the header. skipping some lines my code looks like this:
position = SkyCoord(ra=ra, dec=dec, frame='fk5', unit='deg')  # Object's position
wcs = WCS(header)
center = wcs.all_world2pix(position.ra, position.dec, 0)  # Put object at center
cutout = Cutout2D(image_data, center, size, wcs=wcs)
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=wcs)  # Change axes to WCS
ra = ax.coords[0]
dec = ax.coords[1]
ra.set_ticks(spacing=4. * u.arcsec)
dec.set_ticks(spacing=4. * u.arcsec)
plt.imshow(cutout.data, cmap='gray', norm=norm_linear, origin='lower')

I get images like this:

as you can see the grid lines of the axes aren't aligned.
The best I could achieve is rotating the image itself (using 'orientat' from the header which tells me in degrees the image orientation), and changing the header itself with some piece of code I found (but not sure is working properly):
position = SkyCoord(ra=ra, dec=dec, frame='fk5', unit='deg')  # Object's position
orientat_deg = header['ORIENTAT']  # Get image orientation
h1 = header.copy()  # Copy of the original header
h1.update(
    cd1_1=-np.hypot(header["CD1_1"], header["CD1_2"]),
    cd1_2=0.0,
    cd2_1=0.0,
    cd2_2=np.hypot(header["CD2_1"], header["CD2_2"]),
    orientat=0.0)  # Update wcs to fit aligned wcs
wcs_rotate = WCS(h1)
center = wcs.all_world2pix(position.ra, position.dec, 0)  # Put object at center
cutout = Cutout2D(image_data, center, size, wcs=wcs_rotate)
rotated_img = ndimage.rotate(cutout.data, -orientat_deg, reshape=False)  # Create rotated image
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=wcs_rotate)  # Change axes to fixed wcs
ra = ax.coords[0]
dec = ax.coords[1]
ra.set_ticks(spacing=4. * u.arcsec)
dec.set_ticks(spacing=4. * u.arcsec)
plt.imshow(rotated_img, cmap='gray', norm=norm_linear, origin='lower')  # Plot rotated image with rotated axes

the image I get:

it would seem this messy piece of code works, the only problem is that the real coordinates for this object are: Longitude 00h09m11.577s, Latitude -00d36m54.73s (object's name SDSS J000911.57-003654.7), which isn't quite the coordinates presented on my axes.
I hope someone has a solution, Thank you.

**Tags:** image-processing, alignment, fits-header

> **Comments:**
> **username_1**: Not a proper answer but maybe [reproject](https://reproject.readthedocs.io/en/stable/) might do what you want ? However your original image isn't showing the object near the correct coordinates either. What is the origin of the image and its WCS ? Can you display the image in an image viewer such as ds9 and see if the coordinates for the object are correct there (indicating an Astropy/plotting issue) or not (indicating an issue with the WCS fit in the original FITS image) ?  
> **username_0**: reproject (as does astroalign) seem to be more about aligning 2 different images to each other, rather than aligning one image north. I might be wrong, but I just couldn't find something that works for what I need (which I would expect is a very basic property in astro, so why is it so hard to find).  The first image shouldn't display the correct coordinates, since the grid isn't aligned at all (at least I think so), displaying the image in ds9 gives the correct coordinates. The images are from HST, the wcs is from the header of the fits file.  
> **username_2**: I installed montage and montage-wrapper as suggested in one of astropy issues in github and followed this link (also suggested in that issue) https://stackoverflow.com/a/51967697/2527220 and it worked for me.  

---

## 1 answers

### Answer by username_3 on 2023-03-12. Score: 1

Because you cut the image and rotated it, the old reference is no longer there.

Try this and it works perfectly for me:

After fixing the cutout center on original image `center = wcs.all_world2pix(RA, Dec, 0)` and cutout size `size=(size_x,size_y)` of your cutout2D image, please update not only the WCS matrix elements in the new WCS but also the reference pixels `CRPIX1 = size_x/2`, `CRPIX2 = size_y/2` and positions `CRVAL1 = RA`, `CRVAL2 = DEC`.

Setting `reshape=False` in `scipy.ndimage.rotate` is important because you don't want the center reference pixel in the cutout image changes to other pixel place.

And please take care about the sign of renewed WCS matrix elements, although it is just the orientation and it depends on you.


---

