Выпуск перевода Всемирной системы координат в декартову систему координат. - PullRequest
0 голосов
/ 02 января 2019

У меня есть два подходящих изображения из WFC3, которые я пытаюсь объединить с программой на C #.Когда я пытаюсь объединить несколько изображений, я не думаю, что значения, которые я получаю для моих координат x / y (рассчитанных по прямому восхождению / склонению), являются правильными.Я ожидаю, что окончательное изображение будет примерно той же ширины, что и два изображения вместе взятых, но оно окажется примерно такой же ширины и примерно в два раза больше высоты.Я знаю, что окончательное изображение должно быть примерно в два раза больше ширины одного изображения, потому что я вручную объединил изображения в фотошопе, и окончательное изображение было примерно в два раза шире, чем любое из двух исходных изображений.

ПРИМЕЧАНИЕ: когда я говорю «изображение», они соответствуют изображениям, поэтому они представляют собой просто набор отдельных значений в файле, поэтому для их объединения я создаю новый файл и инициализирую правильное количество отдельных значений (width * height) до нуля, а затем введите значения из изображений, которые я использую для объединения.Они не являются jpg или tif или png.

Я использую следующую формулу для перехода от мировой системы координат к декартовой: формула (поскольку расстояние одинаково для всех): x = cos (dec) * cos(ra) y = cos (dec) * sin (ra)

Я получаю правильное восхождение и склонение из заголовка файла соответствия.

Для окончательных размеров изображения я вычисляюрасстояние между x1 и x2 и создайте новое изображение, которое будет иметь ширину 1/2 изображения 1 + расстояние + ширина изображения 2 1/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, и программа находится в стадии разработки.

1 Ответ

0 голосов
/ 11 января 2019

Я думаю, что ваша программа изображений уже выполняет вращение, и вы должны сделать это тоже.

Если я поверну координаты, которые вы вычислили на 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));
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...