【问题标题】:Issue translating World Coordinate system to cartesian coordinate将世界坐标系转换为笛卡尔坐标的问题
【发布时间】:2019-01-02 06:24:06
【问题描述】:

我有两个来自 WFC3 的适合图像,我正在尝试将它们与 C# 程序结合使用。当我尝试组合多个图像时,我认为我得到的 x/y 坐标值(根据赤经/赤纬计算)不正确。我期望最终图像的宽度与两个图像组合的宽度大致相同,但结果却是大约相同的宽度和大约两倍的高度。我知道最终图像应该是单个图像宽度的两倍,因为我在 Photoshop 中手动组合了图像,最终图像的宽度大约是两个原始图像中的任何一个的两倍。

注意:当我说“图像”时,它们是适合图像,因此它们只是文件中的一堆单个值,因此为了将它们组合起来,我创建了一个新文件并初始化正确数量的单个值(宽度 * 高度) 到零,然后从我用来组合的图像中填充值。它们不是 jpg、tif 或 png。

我正在使用以下公式从世界坐标系更改为笛卡尔坐标系: 公式是(因为距离对所有事物都是相同的): x = cos(dec) * cos(ra) y = cos(dec) * sin(ra)

我从 fit 文件的标题中得到正确的上升和赤纬。

对于最终图像尺寸,我计算 x1 和 x2 之间的距离并创建一个新图像,即 1/2 图像 1 宽度 + 距离 + 1/2 图像 2 宽度。对于最终高度,我对 y 和图像高度进行了类似的计算。

图像也有一个旋转组件,但我忽略了这一点,因为两个图像共享相同的旋转。这可能是我的问题的一部分。

public const double PixelsPerArcSecond = .039; // per WFC3 spec from Nasa

public static ImageDataModel Combine(List<ImageDataModel> inputImages)
{
    //  Right ascension is CRVAL1
    //  Declination is CRVAL2

    //  formula is (since distance is the same for everything):
    //     x = cos(dec) * cos(ra)
    //     y = cos(dec) * sin(ra)

    ImageDataModel returnImage = new ImageDataModel();
    ImageDataModel bm = inputImages[0];

    double x1, y1, x2, y2;

    x1 = Math.Cos(bm.CRVAL2) * Math.Cos(bm.CRVAL1);
    y1 = Math.Cos(bm.CRVAL2) * Math.Sin(bm.CRVAL1);

    int mult = 4; // todo: set this based off of the bitpix of the incoming images.

    for (int i = 1; i < inputImages.Count; i++)
    {
        ImageDataModel cm = inputImages[i];

        x2 = Math.Cos(cm.CRVAL2) * Math.Cos(cm.CRVAL1);
        y2 = Math.Cos(cm.CRVAL2) * Math.Sin(cm.CRVAL1);

        double dx = x1 - x2;
        double dy = y1 - y2;

        int distX = (int)((dx * 3600) / PixelsPerArcSecond);
        int distY = (int)((dy * 3600) / PixelsPerArcSecond);

        // This is what I expect to be wider than tall, but the converse is true.
        int w = Math.Abs(distX) + (bm.ImageWidth / 2) + (cm.ImageWidth / 2);
        int h = Math.Abs(distY) + (bm.ImageHeight / 2) + (cm.ImageHeight / 2);
        // This is where the two images are combined into the final image.
        ImageDataModel imd = CombineTwoImages(bm, cm, i, w, h, mult);
        bm = imd;
    }

    return returnImage;
}

我期待这样的图像:
http://wierdling.net/stack-overflow-images/ManuallyCombined.png

但是得到这个:
http://wierdling.net/stack-overflow-images/CombinedTest.png

第一张图片的统计数据为:宽度 = 4139,高度 = 4535,RA = 350.1584456860353 (CRVAL1),DEC = 61.16155335032816 (CRVAL2),ORIENTAT = -125

第二张图片的统计数据是:宽度 = 4139,高度 = 4535,RA = 350.1159150008405 (CRVAL1),DEC = 61.19543100394401 (CRVAL2),ORIENTAT = -125

最终预期宽度接近 7733,高度接近 4773。

最终实际宽度为4284,高度为7662。

有人知道我做错了什么吗?

程序的完整源代码可以从https://bitbucket.org/wierdling/fitscombiner/src/master/下载

它目前仅适用于 WFC3 数据,该程序正在进行中。

【问题讨论】:

  • 请注意,您的代码需要登录才能查看。最好使用PasteBin 或类似服务(例如: Github's Gists。这将为查看者提供即时代码可读性,而无需帐户+登录等。

标签: c# astronomy fits


【解决方案1】:

我认为您的图像程序已经进行了旋转,您也应该这样做。

如果我将您计算的坐标旋转 125 度,然后计算坐标 x1 与左侧的距离,对于 x2 和 y 坐标,我得到的宽度为 6725,高度为 6166。

并不完美,但我认为它朝着正确的方向发展。

希望有所帮助。

    public static ImageDataModel Combine(List<ImageDataModel> inputImages)
    {
        //  Right ascension is CRVAL1
        //  Declination is CRVAL2

        //  formula is (since distance is the same for everything):
        //     x = cos(dec) * cos(ra)
        //     y = cos(dec) * sin(ra)

        ImageDataModel returnImage = new ImageDataModel();
        ImageDataModel bm = inputImages[0];

        double x1, y1, x2, y2;

        x1 = Math.Cos(bm.CRVAL2) * Math.Cos(bm.CRVAL1);
        y1 = Math.Cos(bm.CRVAL2) * Math.Sin(bm.CRVAL1);
        var values = Rotate(0 - bm.Orientation, x1, y1);
        x1 = values.x;
        y1 = values.y;
        int mult = 4; // todo: set this based off of the bitpix of the incoming images.

        for (int i = 1; i < inputImages.Count; i++)
        {
            ImageDataModel cm = inputImages[i];

            x2 = Math.Cos(cm.CRVAL2) * Math.Cos(cm.CRVAL1);
            y2 = Math.Cos(cm.CRVAL2) * Math.Sin(cm.CRVAL1);
            var values2 = Rotate(0 - bm.Orientation, x2, y2);

            x2 = values2.x;
            y2 = values2.y;

            double dx = x1 - x2;
            double dy = y1 - y2;

            int distX = (int)((dx * 3600) / PixelsPerArcSecond);
            int distY = (int)((dy * 3600) / PixelsPerArcSecond);

            double width = (1.0 + x1) * (bm.ImageWidth / 2) + (1.0 - x2) * (cm.ImageWidth / 2) + Math.Abs(distX);
            double height = (1.0 + y1) * (bm.ImageHeight / 2) + (1.0 - y2) * (cm.ImageHeight / 2) + Math.Abs(distY);
            // This is what I expect to be wider than tall, but the converse is true.
            int w = Math.Abs(distX) + (bm.ImageWidth / 2) + (cm.ImageWidth / 2);
            int h = Math.Abs(distY) + (bm.ImageHeight / 2) + (cm.ImageHeight / 2);
            // This is where the two images are combined into the final image.
            ImageDataModel imd = CombineTwoImages(bm, cm, i, w, h, mult);
            bm = imd;
        }

        return returnImage;
    }

    private static (double x, double y) Rotate(int angle, double x, double y)
    {
        double rad = Math.PI * angle / 180.0;

        return (x * Math.Cos(rad) - y * Math.Sin(rad), x * Math.Sin(rad) + y * Math.Cos(rad));
    }

【讨论】:

    猜你喜欢
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多