Add support for WCS
This commit is contained in:
+2
-1
@@ -19,6 +19,7 @@ find_library(GSLCBLAS_LIB gslcblas REQUIRED)
|
|||||||
find_library(EXIF_LIB exif REQUIRED)
|
find_library(EXIF_LIB exif REQUIRED)
|
||||||
find_library(FITS_LIB cfitsio REQUIRED)
|
find_library(FITS_LIB cfitsio REQUIRED)
|
||||||
find_library(RAW_LIB NAMES raw_r REQUIRED)
|
find_library(RAW_LIB NAMES raw_r REQUIRED)
|
||||||
|
find_library(WCS_LIB wcs REQUIRED)
|
||||||
|
|
||||||
set(TENMON_SRC
|
set(TENMON_SRC
|
||||||
about.cpp
|
about.cpp
|
||||||
@@ -58,7 +59,7 @@ else()
|
|||||||
target_link_directories(tenmon PRIVATE 3rdparty/lib/Linux)
|
target_link_directories(tenmon PRIVATE 3rdparty/lib/Linux)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(tenmon Qt5::Widgets Qt5::Sql ${OpenCV_LIBS} ${GSL_LIB} ${GSLCBLAS_LIB} ${EXIF_LIB} ${FITS_LIB} ${RAW_LIB})
|
target_link_libraries(tenmon Qt5::Widgets Qt5::Sql ${OpenCV_LIBS} ${GSL_LIB} ${GSLCBLAS_LIB} ${EXIF_LIB} ${FITS_LIB} ${RAW_LIB} ${WCS_LIB})
|
||||||
target_link_libraries(tenmon PCL lcms lz4 RFC6234 zlib)
|
target_link_libraries(tenmon PCL lcms lz4 RFC6234 zlib)
|
||||||
|
|
||||||
if(LIBRAW_STATIC)
|
if(LIBRAW_STATIC)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include "imageinfo.h"
|
#include "imageinfo.h"
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QTime>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
#include <wcslib/wcshdr.h>
|
||||||
|
#include <wcslib/wcsfix.h>
|
||||||
|
|
||||||
static const QVector<QByteArray> noEditableKey = {"SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "EXTEND", "BZERO", "BSCALE"};
|
static const QVector<QByteArray> noEditableKey = {"SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "EXTEND", "BZERO", "BSCALE"};
|
||||||
|
|
||||||
@@ -47,3 +50,90 @@ void ImageInfo::setInfo(const ImageInfoData &info)
|
|||||||
}
|
}
|
||||||
expandAll();
|
expandAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WCSData::freeWCS()
|
||||||
|
{
|
||||||
|
wcsvfree(&nwcs, &wcs);
|
||||||
|
nwcs = 0;
|
||||||
|
wcs = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCSData::WCSData(char *header, int nrec)
|
||||||
|
{
|
||||||
|
int stat[NWCSFIX];
|
||||||
|
int nreject = 0;
|
||||||
|
int status = wcspih(header, nrec, 1, 0, &nreject, &nwcs, &wcs);
|
||||||
|
if(status != 0)
|
||||||
|
{
|
||||||
|
freeWCS();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
status = wcsfix(0, 0, wcs, stat);
|
||||||
|
if(status != 0 || wcs->crpix[0] == 0)
|
||||||
|
freeWCS();
|
||||||
|
}
|
||||||
|
|
||||||
|
WCSData::~WCSData()
|
||||||
|
{
|
||||||
|
if(wcs)
|
||||||
|
freeWCS();
|
||||||
|
}
|
||||||
|
|
||||||
|
SkyPoint WCSData::pixelToWorld(QPointF pixel) const
|
||||||
|
{
|
||||||
|
if(wcs == nullptr)return SkyPoint();
|
||||||
|
double pixcrd[2] = {pixel.x(), pixel.y()};
|
||||||
|
double imgcrd[8] = {0};
|
||||||
|
double phi = 0;
|
||||||
|
double theta = 0;
|
||||||
|
double world[8] = {0};
|
||||||
|
int stat[NWCSFIX] = {0};
|
||||||
|
int status = wcsp2s(wcs, 1, 2, pixcrd, imgcrd, &phi, &theta, world, stat);
|
||||||
|
if(status == 0)
|
||||||
|
{
|
||||||
|
return SkyPoint(world[0], world[1]);
|
||||||
|
}
|
||||||
|
return SkyPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF WCSData::worldToPixel(SkyPoint point) const
|
||||||
|
{
|
||||||
|
return QPointF();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WCSData::calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec)
|
||||||
|
{
|
||||||
|
minRa = -1000;
|
||||||
|
maxRa = 1000;
|
||||||
|
minDec = -1000;
|
||||||
|
maxDec = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkyPoint::SkyPoint() : ra(NAN), dec(NAN)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SkyPoint::SkyPoint(double ra, double dec) : ra(ra), dec(dec)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyPoint::set(double ra, double dec)
|
||||||
|
{
|
||||||
|
this->ra = ra;
|
||||||
|
this->dec = dec;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SkyPoint::toString() const
|
||||||
|
{
|
||||||
|
if(std::isnan(ra) || std::isnan(dec))
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
QTime t(0, 0);
|
||||||
|
t = t.addSecs(ra * 240);
|
||||||
|
|
||||||
|
double deg, min, sec;
|
||||||
|
min = std::modf(dec, °) * 60;
|
||||||
|
sec = std::modf(min, &min) * 60;
|
||||||
|
return QString("RA: %1 DEC: %2° %3' %4\"").arg(t.toString("HH'h' mm'm' ss's'")).arg(deg, 2, 'f', 0, '0').arg(min, 2, 'f', 0, '0').arg(sec, 2, 'f', 0, '0');
|
||||||
|
}
|
||||||
|
|||||||
+30
@@ -2,6 +2,8 @@
|
|||||||
#define IMAGEINFO_H
|
#define IMAGEINFO_H
|
||||||
|
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
#include <wcslib/wcs.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
struct FITSRecord
|
struct FITSRecord
|
||||||
{
|
{
|
||||||
@@ -11,10 +13,38 @@ struct FITSRecord
|
|||||||
bool editable() const;
|
bool editable() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SkyPoint
|
||||||
|
{
|
||||||
|
double ra = NAN;
|
||||||
|
double dec = NAN;
|
||||||
|
public:
|
||||||
|
SkyPoint();
|
||||||
|
SkyPoint(double ra, double dec);
|
||||||
|
void set(double ra, double dec);
|
||||||
|
double RA() const { return ra; }
|
||||||
|
double DEC() const { return dec; }
|
||||||
|
QString toString() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WCSData
|
||||||
|
{
|
||||||
|
int nwcs = 0;
|
||||||
|
struct wcsprm *wcs = nullptr;
|
||||||
|
void freeWCS();
|
||||||
|
public:
|
||||||
|
WCSData();
|
||||||
|
WCSData(char *header, int nrec);
|
||||||
|
~WCSData();
|
||||||
|
SkyPoint pixelToWorld(QPointF pixel) const;
|
||||||
|
QPointF worldToPixel(SkyPoint point) const;
|
||||||
|
void calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec);
|
||||||
|
};
|
||||||
|
|
||||||
struct ImageInfoData
|
struct ImageInfoData
|
||||||
{
|
{
|
||||||
QVector<FITSRecord> fitsHeader;
|
QVector<FITSRecord> fitsHeader;
|
||||||
QVector<QPair<QString, QString>> info;
|
QVector<QPair<QString, QString>> info;
|
||||||
|
std::shared_ptr<WCSData> wcs;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ImageInfoData);
|
Q_DECLARE_METATYPE(ImageInfoData);
|
||||||
|
|||||||
+23
-7
@@ -85,7 +85,7 @@ ImageWidget::~ImageWidget()
|
|||||||
makeCurrent();
|
makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageWidget::setImage(std::shared_ptr<RawImage> &image, int index)
|
void ImageWidget::setImage(std::shared_ptr<RawImage> image, int index)
|
||||||
{
|
{
|
||||||
if(image == nullptr)return;
|
if(image == nullptr)return;
|
||||||
|
|
||||||
@@ -112,6 +112,11 @@ void ImageWidget::setImage(std::shared_ptr<RawImage> &image, int index)
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageWidget::setWCS(std::shared_ptr<WCSData> wcs)
|
||||||
|
{
|
||||||
|
m_wcs = wcs;
|
||||||
|
}
|
||||||
|
|
||||||
void ImageWidget::setScale(float scale)
|
void ImageWidget::setScale(float scale)
|
||||||
{
|
{
|
||||||
m_scale = scale;
|
m_scale = scale;
|
||||||
@@ -456,12 +461,19 @@ void ImageWidget::mouseMoveEvent(QMouseEvent *event)
|
|||||||
QVector2D pos = QVector2D(event->pos());
|
QVector2D pos = QVector2D(event->pos());
|
||||||
QVector2D pix = (pos + offset) / m_scale;
|
QVector2D pix = (pos + offset) / m_scale;
|
||||||
QVector3D rgb;
|
QVector3D rgb;
|
||||||
|
|
||||||
|
SkyPoint sky;
|
||||||
|
if(m_wcs)
|
||||||
|
{
|
||||||
|
sky = m_wcs->pixelToWorld(QPointF(pix.x(), pix.y()));
|
||||||
|
}
|
||||||
|
|
||||||
if(m_rawImage->pixel(pix.x(), pix.y(), rgb))
|
if(m_rawImage->pixel(pix.x(), pix.y(), rgb))
|
||||||
{
|
{
|
||||||
if(m_bwImg)
|
if(m_bwImg)
|
||||||
emit status(tr("L: %1").arg(rgb.x()));
|
emit status(tr("L:%1 %2 X:%3 Y:%4").arg(rgb.x()).arg(sky.toString()).arg((int)pix.x()).arg((int)pix.y()));
|
||||||
else
|
else
|
||||||
emit status(tr("R: %1 G: %2 B: %3").arg(rgb.x()).arg(rgb.y()).arg(rgb.z()));
|
emit status(tr("R:%1 G:%2 B:%3 %4 X:%5 Y:%6").arg(rgb.x()).arg(rgb.y()).arg(rgb.z()).arg(sky.toString()).arg((int)pix.x()).arg((int)pix.y()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -551,13 +563,17 @@ ImageScrollAreaGL::~ImageScrollAreaGL()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageScrollAreaGL::setImage(std::shared_ptr<RawImage> image, int index)
|
void ImageScrollAreaGL::setImage(Image *image)
|
||||||
{
|
{
|
||||||
m_imageWidget->setImage(image, index);
|
if(image && image->rawImage())
|
||||||
m_imgWidth = image->width();
|
{
|
||||||
m_imgHeight = image->height();
|
m_imageWidget->setImage(image->rawImage(), image->number());
|
||||||
|
m_imageWidget->setWCS(image->info().wcs);
|
||||||
|
m_imgWidth = image->rawImage()->width();
|
||||||
|
m_imgHeight = image->rawImage()->height();
|
||||||
if(m_bestFit)bestFit();
|
if(m_bestFit)bestFit();
|
||||||
updateScrollbars();
|
updateScrollbars();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageWidget *ImageScrollAreaGL::imageWidget()
|
ImageWidget *ImageScrollAreaGL::imageWidget()
|
||||||
|
|||||||
+4
-2
@@ -40,6 +40,7 @@ class ImageWidget : public QOpenGLWidget
|
|||||||
std::unique_ptr<QOpenGLPixelTransferOptions> m_transferOptions;
|
std::unique_ptr<QOpenGLPixelTransferOptions> m_transferOptions;
|
||||||
std::unique_ptr<QOpenGLTexture> m_thumbnailTexture;
|
std::unique_ptr<QOpenGLTexture> m_thumbnailTexture;
|
||||||
std::shared_ptr<RawImage> m_rawImage;
|
std::shared_ptr<RawImage> m_rawImage;
|
||||||
|
std::shared_ptr<WCSData> m_wcs;
|
||||||
int m_width, m_height;
|
int m_width, m_height;
|
||||||
int m_imgWidth, m_imgHeight;
|
int m_imgWidth, m_imgHeight;
|
||||||
int m_currentImg;
|
int m_currentImg;
|
||||||
@@ -61,8 +62,9 @@ class ImageWidget : public QOpenGLWidget
|
|||||||
public:
|
public:
|
||||||
explicit ImageWidget(Database *database, QWidget *parent = nullptr);
|
explicit ImageWidget(Database *database, QWidget *parent = nullptr);
|
||||||
~ImageWidget() override;
|
~ImageWidget() override;
|
||||||
void setImage(std::shared_ptr<RawImage> &image, int index);
|
void setImage(std::shared_ptr<RawImage> image, int index);
|
||||||
void setImage(const QPixmap &pixmap);
|
void setImage(const QPixmap &pixmap);
|
||||||
|
void setWCS(std::shared_ptr<WCSData> wcs);
|
||||||
void setScale(float scale);
|
void setScale(float scale);
|
||||||
void blockRepaint(bool block);
|
void blockRepaint(bool block);
|
||||||
void allocateThumbnails(const QStringList &paths);
|
void allocateThumbnails(const QStringList &paths);
|
||||||
@@ -103,7 +105,7 @@ class ImageScrollAreaGL : public QWidget
|
|||||||
public:
|
public:
|
||||||
explicit ImageScrollAreaGL(Database *database, QWidget *parent = nullptr);
|
explicit ImageScrollAreaGL(Database *database, QWidget *parent = nullptr);
|
||||||
~ImageScrollAreaGL() override;
|
~ImageScrollAreaGL() override;
|
||||||
void setImage(std::shared_ptr<RawImage> image, int index);
|
void setImage(Image *image);
|
||||||
ImageWidget* imageWidget();
|
ImageWidget* imageWidget();
|
||||||
void setThumbnails(int count);
|
void setThumbnails(int count);
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <pcl/XISF.h>
|
#include <pcl/XISF.h>
|
||||||
#include "rawimage.h"
|
#include "rawimage.h"
|
||||||
#include "starfit.h"
|
#include "starfit.h"
|
||||||
|
#include "wcslib/wcshdr.h"
|
||||||
|
|
||||||
LoadRunable::LoadRunable(const QString &file, Image *receiver, AnalyzeLevel level, bool thumbnail) :
|
LoadRunable::LoadRunable(const QString &file, Image *receiver, AnalyzeLevel level, bool thumbnail) :
|
||||||
m_file(file),
|
m_file(file),
|
||||||
@@ -166,6 +167,15 @@ int loadFITSHeader(fitsfile *file, ImageInfoData &info)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *header = nullptr;
|
||||||
|
int nrec = 0;
|
||||||
|
fits_hdr2str(file, TRUE, nullptr, 0, &header, &nrec, &status);
|
||||||
|
if(status == 0)
|
||||||
|
{
|
||||||
|
info.wcs = std::make_shared<WCSData>(header, nrec);
|
||||||
|
}
|
||||||
|
fits_free_memory(header, &status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -341,7 +341,7 @@ void MainWindow::pixmapLoaded(Image *image)
|
|||||||
{
|
{
|
||||||
if(image->rawImage())
|
if(image->rawImage())
|
||||||
{
|
{
|
||||||
m_imageGL->setImage(image->rawImage(), image->number());
|
m_imageGL->setImage(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user