Getting rid of opencv
This commit is contained in:
+2
-3
@@ -13,7 +13,6 @@ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
|
|||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
|
||||||
|
|
||||||
find_package(Qt5 COMPONENTS Widgets Sql OpenGL REQUIRED)
|
find_package(Qt5 COMPONENTS Widgets Sql OpenGL REQUIRED)
|
||||||
find_package(OpenCV REQUIRED)
|
|
||||||
find_library(GSL_LIB gsl REQUIRED)
|
find_library(GSL_LIB gsl REQUIRED)
|
||||||
find_library(GSLCBLAS_LIB gslcblas REQUIRED)
|
find_library(GSLCBLAS_LIB gslcblas REQUIRED)
|
||||||
find_library(EXIF_LIB exif REQUIRED)
|
find_library(EXIF_LIB exif REQUIRED)
|
||||||
@@ -70,13 +69,13 @@ endif()
|
|||||||
add_executable(tenmon WIN32 MACOSX_BUNDLE ${tenmon_ICON} ${TENMON_SRC})
|
add_executable(tenmon WIN32 MACOSX_BUNDLE ${tenmon_ICON} ${TENMON_SRC})
|
||||||
|
|
||||||
find_path(FITS_INCLUDE fitsio2.h PATH_SUFFIXES cfitsio REQUIRED)
|
find_path(FITS_INCLUDE fitsio2.h PATH_SUFFIXES cfitsio REQUIRED)
|
||||||
target_include_directories(tenmon PRIVATE ${OpenCV_INCLUDE_DIRS} ${FITS_INCLUDE} ${CMAKE_BINARY_DIR} ${libXISF_SOURCE_DIR})
|
target_include_directories(tenmon PRIVATE ${FITS_INCLUDE} ${CMAKE_BINARY_DIR} ${libXISF_SOURCE_DIR})
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
target_include_directories(tenmon PRIVATE ${GIO_INCLUDE_DIRS})
|
target_include_directories(tenmon PRIVATE ${GIO_INCLUDE_DIRS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(tenmon Qt5::Widgets Qt5::Sql ${OpenCV_LIBS} ${GSL_LIB} ${GSLCBLAS_LIB} ${EXIF_LIB} ${FITS_LIB} ${RAW_LIB} ${WCS_LIB} XISF)
|
target_link_libraries(tenmon Qt5::Widgets Qt5::Sql ${GSL_LIB} ${GSLCBLAS_LIB} ${EXIF_LIB} ${FITS_LIB} ${RAW_LIB} ${WCS_LIB} XISF)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(tenmon "-framework CoreFoundation")
|
target_link_libraries(tenmon "-framework CoreFoundation")
|
||||||
else()
|
else()
|
||||||
|
|||||||
+65
-68
@@ -12,47 +12,48 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
struct RawImageType
|
struct RawImageType
|
||||||
{
|
{
|
||||||
QOpenGLTexture::PixelFormat pixelFormat;
|
QOpenGLTexture::PixelFormat pixelFormat;
|
||||||
QOpenGLTexture::TextureFormat textureFormat;
|
QOpenGLTexture::TextureFormat textureFormat;
|
||||||
QOpenGLTexture::PixelType dataType;
|
QOpenGLTexture::PixelType dataType;
|
||||||
bool bw;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const RawImageType rawImageTypes[] = {
|
RawImageType getRawImageType(const RawImage *img)
|
||||||
{QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, true},
|
|
||||||
{QOpenGLTexture::Red, QOpenGLTexture::R16_UNorm, QOpenGLTexture::UInt16, true},
|
|
||||||
{QOpenGLTexture::Red, QOpenGLTexture::R32F, QOpenGLTexture::Float32, true},
|
|
||||||
#ifdef COLOR_MANAGMENT
|
|
||||||
{QOpenGLTexture::RGB, QOpenGLTexture::SRGB8, QOpenGLTexture::UInt8, false},
|
|
||||||
{QOpenGLTexture::RGBA,QOpenGLTexture::SRGB8_Alpha8, QOpenGLTexture::UInt8, false},
|
|
||||||
#else
|
|
||||||
{QOpenGLTexture::RGB, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, false},
|
|
||||||
{QOpenGLTexture::RGBA,QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, false},
|
|
||||||
#endif
|
|
||||||
{QOpenGLTexture::RGB, QOpenGLTexture::RGB16_UNorm, QOpenGLTexture::UInt16, false},
|
|
||||||
{QOpenGLTexture::RGBA, QOpenGLTexture::RGB16_UNorm, QOpenGLTexture::UInt16, false},
|
|
||||||
{QOpenGLTexture::RGB, QOpenGLTexture::RGB32F, QOpenGLTexture::Float32, false}
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool MANUAL_MIPMAP_GEN = false;
|
|
||||||
|
|
||||||
void setScrollRange(QScrollBar *scrollBar, int newRange)
|
|
||||||
{
|
{
|
||||||
int page = scrollBar->pageStep();
|
RawImageType type;
|
||||||
int pos = scrollBar->value() + page/2;
|
switch(img->type())
|
||||||
int range = scrollBar->maximum() + page;
|
{
|
||||||
float relPos = (float)pos/(float)range;
|
case RawImage::UINT8:
|
||||||
|
if(img->channels() >= 3)
|
||||||
|
type.textureFormat = QOpenGLTexture::SRGB8_Alpha8;
|
||||||
|
else
|
||||||
|
type.textureFormat = QOpenGLTexture::R8_UNorm;
|
||||||
|
type.dataType = QOpenGLTexture::UInt8;
|
||||||
|
break;
|
||||||
|
case RawImage::UINT16:
|
||||||
|
if(img->channels() >= 3)
|
||||||
|
type.textureFormat = QOpenGLTexture::RGBA16_UNorm;
|
||||||
|
else
|
||||||
|
type.textureFormat = QOpenGLTexture::R16_UNorm;
|
||||||
|
type.dataType = QOpenGLTexture::UInt16;
|
||||||
|
break;
|
||||||
|
case RawImage::FLOAT32:
|
||||||
|
if(img->channels() >= 3)
|
||||||
|
type.textureFormat = QOpenGLTexture::RGBA32F;
|
||||||
|
else
|
||||||
|
type.textureFormat = QOpenGLTexture::R32F;
|
||||||
|
type.dataType = QOpenGLTexture::Float32;
|
||||||
|
}
|
||||||
|
|
||||||
if(page >= newRange)
|
if(img->channels() >= 3)
|
||||||
scrollBar->hide();
|
type.pixelFormat = QOpenGLTexture::RGBA;
|
||||||
else
|
else
|
||||||
scrollBar->show();
|
type.pixelFormat = QOpenGLTexture::Red;
|
||||||
|
|
||||||
scrollBar->setRange(0, newRange - page);
|
return type;
|
||||||
scrollBar->setValue(relPos*newRange - page/2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageWidget::ImageWidget(Database *database, QWidget *parent) : QOpenGLWidget(parent)
|
ImageWidget::ImageWidget(Database *database, QWidget *parent) : QOpenGLWidget(parent)
|
||||||
@@ -108,10 +109,12 @@ void ImageWidget::setImage(std::shared_ptr<RawImage> image, int index)
|
|||||||
|
|
||||||
if(!m_image)return;
|
if(!m_image)return;
|
||||||
|
|
||||||
const RawImageType &rawImageType = rawImageTypes[image->type()];
|
RawImageType rawImageType = getRawImageType(image.get());
|
||||||
m_srgb = rawImageType.textureFormat == QOpenGLTexture::SRGB8 || rawImageType.textureFormat == QOpenGLTexture::SRGB8_Alpha8;
|
m_srgb = rawImageType.textureFormat == QOpenGLTexture::SRGB8_Alpha8;
|
||||||
m_bwImg = rawImageType.bw;
|
m_bwImg = image->channels() == 1;
|
||||||
|
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
m_image->destroy();
|
m_image->destroy();
|
||||||
m_image->setAutoMipMapGenerationEnabled(false);
|
m_image->setAutoMipMapGenerationEnabled(false);
|
||||||
m_image->setFormat(rawImageType.textureFormat);
|
m_image->setFormat(rawImageType.textureFormat);
|
||||||
@@ -122,40 +125,33 @@ void ImageWidget::setImage(std::shared_ptr<RawImage> image, int index)
|
|||||||
m_image->setWrapMode(QOpenGLTexture::ClampToEdge);
|
m_image->setWrapMode(QOpenGLTexture::ClampToEdge);
|
||||||
m_image->setBorderColor(0, 0, 0, 0);
|
m_image->setBorderColor(0, 0, 0, 0);
|
||||||
m_image->setData(0, rawImageType.pixelFormat, rawImageType.dataType, (const void*)image->data(), m_transferOptions.get());
|
m_image->setData(0, rawImageType.pixelFormat, rawImageType.dataType, (const void*)image->data(), m_transferOptions.get());
|
||||||
|
m_image->generateMipMaps();
|
||||||
|
qDebug() << "setImage" << timer.elapsed();
|
||||||
|
|
||||||
auto sRGB_linear = [](cv::Point3f &pixel, const int *pos)
|
/*QElapsedTimer timer;
|
||||||
|
RawImage xxx(8192, 8192, 4, RawImage::UINT32);
|
||||||
|
uint32_t *p = (uint32_t*)xxx.data();
|
||||||
|
for(int i=0; i<8192*8192*4; i++)
|
||||||
|
p[i] = rand();
|
||||||
|
auto test = [&](QOpenGLTexture::PixelFormat format)
|
||||||
{
|
{
|
||||||
pixel.x = pixel.x <= 0.04045f ? pixel.x / 12.92f : std::pow((pixel.x + 0.055) / 1.055f, 2.4f);
|
timer.start();
|
||||||
pixel.y = pixel.y <= 0.04045f ? pixel.y / 12.92f : std::pow((pixel.y + 0.055) / 1.055f, 2.4f);
|
m_image->destroy();
|
||||||
pixel.z = pixel.z <= 0.04045f ? pixel.z / 12.92f : std::pow((pixel.z + 0.055) / 1.055f, 2.4f);
|
//m_image->setAutoMipMapGenerationEnabled(false);
|
||||||
|
m_image->setFormat(QOpenGLTexture::TextureFormat::RGBA8_UNorm);
|
||||||
|
m_image->setSize(8192, 8192);
|
||||||
|
//m_image->setMipLevels([&](){ int c = 0; int s = std::min(m_imgWidth, m_imgHeight); while(s>>=1)c++; return c; }());
|
||||||
|
m_image->allocateStorage();
|
||||||
|
m_image->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
||||||
|
m_image->setWrapMode(QOpenGLTexture::ClampToEdge);
|
||||||
|
m_image->setBorderColor(0, 0, 0, 0);
|
||||||
|
m_image->setData(0, format, QOpenGLTexture::UInt8, (const void*)p, m_transferOptions.get());
|
||||||
|
qDebug() << format << timer.elapsed();
|
||||||
};
|
};
|
||||||
|
test(QOpenGLTexture::PixelFormat::BGR);
|
||||||
auto linear_sRGB = [](cv::Point3f &pixel, const int *pos)
|
test(QOpenGLTexture::PixelFormat::RGB);
|
||||||
{
|
test(QOpenGLTexture::PixelFormat::BGRA);
|
||||||
pixel.x = pixel.x <= 0.0031308f ? pixel.x * 12.92f : 1.055f * std::pow(pixel.x , 1/2.4f) - 0.055f;
|
test(QOpenGLTexture::PixelFormat::RGBA);*/
|
||||||
pixel.y = pixel.y <= 0.0031308f ? pixel.y * 12.92f : 1.055f * std::pow(pixel.y , 1/2.4f) - 0.055f;
|
|
||||||
pixel.z = pixel.z <= 0.0031308f ? pixel.z * 12.92f : 1.055f * std::pow(pixel.z , 1/2.4f) - 0.055f;
|
|
||||||
};
|
|
||||||
|
|
||||||
//AMD OpenGL driver on Windows doesn't generate mipmaps for sRGB textures correctly
|
|
||||||
if(m_srgb && MANUAL_MIPMAP_GEN)
|
|
||||||
{
|
|
||||||
cv::Mat img = image->mat();
|
|
||||||
img.convertTo(img, CV_32FC3, 1/255.0);
|
|
||||||
img.forEach<cv::Point3f>(sRGB_linear);
|
|
||||||
cv::Size size(img.cols, img.rows);
|
|
||||||
for(int i=1; i<m_image->mipLevels(); i++)
|
|
||||||
{
|
|
||||||
cv::Mat mip;
|
|
||||||
size /= 2;
|
|
||||||
cv::resize(img, mip, size);
|
|
||||||
mip.copyTo(img);
|
|
||||||
mip.forEach<cv::Point3f>(linear_sRGB);
|
|
||||||
mip.convertTo(mip, CV_8UC3, 255);
|
|
||||||
m_image->setData(i, rawImageType.pixelFormat, rawImageType.dataType, (const void*)mip.ptr(), m_transferOptions.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else m_image->generateMipMaps();
|
|
||||||
|
|
||||||
if(m_debayerTex)
|
if(m_debayerTex)
|
||||||
{
|
{
|
||||||
@@ -308,7 +304,8 @@ void ImageWidget::thumbnailLoaded(const Image *image)
|
|||||||
{
|
{
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
const RawImage *raw = image->thumbnail();
|
const RawImage *raw = image->thumbnail();
|
||||||
m_thumbnailTexture->setData(0, image->number(), QOpenGLTexture::RGB, QOpenGLTexture::UInt16, raw->data(), m_transferOptions.get());
|
if(!raw)return;
|
||||||
|
m_thumbnailTexture->setData(0, image->number(), QOpenGLTexture::RGBA, QOpenGLTexture::UInt16, raw->data(), m_transferOptions.get());
|
||||||
float a = raw->thumbAspect();
|
float a = raw->thumbAspect();
|
||||||
int sizes[3] = { std::max(1, a > 1.0f ? THUMB_SIZE : (int)(THUMB_SIZE * a)), std::max(1, a < 1.0f ? THUMB_SIZE : (int)(THUMB_SIZE / a)), image->number() };
|
int sizes[3] = { std::max(1, a > 1.0f ? THUMB_SIZE : (int)(THUMB_SIZE * a)), std::max(1, a < 1.0f ? THUMB_SIZE : (int)(THUMB_SIZE / a)), image->number() };
|
||||||
m_sizesDirty = true;
|
m_sizesDirty = true;
|
||||||
@@ -612,7 +609,7 @@ void ImageWidget::mouseMoveEvent(QMouseEvent *event)
|
|||||||
if(!m_showThumbnails && m_rawImage)
|
if(!m_showThumbnails && m_rawImage)
|
||||||
{
|
{
|
||||||
QVector2D pix = getImagePixelCoord(QVector2D(event->pos()));
|
QVector2D pix = getImagePixelCoord(QVector2D(event->pos()));
|
||||||
QVector3D rgb;
|
double r,g,b;
|
||||||
|
|
||||||
SkyPoint sky;
|
SkyPoint sky;
|
||||||
if(m_wcs)
|
if(m_wcs)
|
||||||
@@ -620,12 +617,12 @@ void ImageWidget::mouseMoveEvent(QMouseEvent *event)
|
|||||||
m_wcs->pixelToWorld(QPointF(pix.x(), pix.y()), sky);
|
m_wcs->pixelToWorld(QPointF(pix.x(), pix.y()), sky);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_rawImage->pixel(pix.x(), pix.y(), rgb))
|
if(m_rawImage->pixel(pix.x(), pix.y(), r, g, b))
|
||||||
{
|
{
|
||||||
if(m_bwImg)
|
if(m_bwImg)
|
||||||
emit status(tr("L:%1").arg(rgb.x()), tr("X:%3 Y:%4").arg((int)pix.x()).arg((int)pix.y()), sky.toString());
|
emit status(tr("L:%1").arg(r), tr("X:%3 Y:%4").arg((int)pix.x()).arg((int)pix.y()), sky.toString());
|
||||||
else
|
else
|
||||||
emit status(tr("R:%1 G:%2 B:%3").arg(rgb.x()).arg(rgb.y()).arg(rgb.z()), tr("X:%3 Y:%4").arg((int)pix.x()).arg((int)pix.y()), sky.toString());
|
emit status(tr("R:%1 G:%2 B:%3").arg(r).arg(g).arg(b), tr("X:%3 Y:%4").arg((int)pix.x()).arg((int)pix.y()), sky.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+69
-86
@@ -115,7 +115,7 @@ bool loadRAW(const QString path, ImageInfoData &info, RawImage **image)
|
|||||||
out[d++] = p;
|
out[d++] = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*image = new RawImage(rawdata.sizes.width, rawdata.sizes.height, RawImage::UINT16);
|
*image = new RawImage(rawdata.sizes.width, rawdata.sizes.height, 1, RawImage::UINT16);
|
||||||
memcpy((*image)->data(), &out[0], sizeof(uint16_t)*d);
|
memcpy((*image)->data(), &out[0], sizeof(uint16_t)*d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,28 +212,35 @@ bool loadFITS(const QString path, ImageInfoData &info, RawImage **image)
|
|||||||
|
|
||||||
if(naxis >= 2 && naxis <= 3 && status == 0)
|
if(naxis >= 2 && naxis <= 3 && status == 0)
|
||||||
{
|
{
|
||||||
int cvtype;
|
RawImage::DataType type;
|
||||||
int fitstype;
|
int fitstype;
|
||||||
std::vector<cv::Mat> cvimg;
|
|
||||||
long fpixel[3] = {1,1,1};
|
long fpixel[3] = {1,1,1};
|
||||||
switch(imgtype)
|
switch(imgtype)
|
||||||
{
|
{
|
||||||
case BYTE_IMG:
|
case BYTE_IMG:
|
||||||
cvtype = CV_8U;
|
type = RawImage::UINT8;
|
||||||
fitstype = TBYTE;
|
fitstype = TBYTE;
|
||||||
break;
|
break;
|
||||||
case SHORT_IMG:
|
case SHORT_IMG:
|
||||||
cvtype = CV_16S;
|
type = RawImage::UINT16;
|
||||||
fitstype = TSHORT;
|
fitstype = TSHORT;
|
||||||
break;
|
break;
|
||||||
case USHORT_IMG:
|
case USHORT_IMG:
|
||||||
cvtype = CV_16U;
|
type = RawImage::UINT16;
|
||||||
fitstype = TUSHORT;
|
fitstype = TUSHORT;
|
||||||
break;
|
break;
|
||||||
|
case ULONG_IMG:
|
||||||
|
type = RawImage::UINT32;
|
||||||
|
fitstype = TUINT;
|
||||||
|
break;
|
||||||
case FLOAT_IMG:
|
case FLOAT_IMG:
|
||||||
cvtype = CV_32F;
|
type = RawImage::FLOAT32;
|
||||||
fitstype = TFLOAT;
|
fitstype = TFLOAT;
|
||||||
break;
|
break;
|
||||||
|
case DOUBLE_IMG:
|
||||||
|
type = RawImage::FLOAT64;
|
||||||
|
fitstype = TDOUBLE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
info.info.append({QObject::tr("Error"), QObject::tr("Unsupported sample format")});
|
info.info.append({QObject::tr("Error"), QObject::tr("Unsupported sample format")});
|
||||||
goto noload;
|
goto noload;
|
||||||
@@ -247,26 +254,28 @@ bool loadFITS(const QString path, ImageInfoData &info, RawImage **image)
|
|||||||
info.info.append({QObject::tr("Width"), QString::number(naxes[0])});
|
info.info.append({QObject::tr("Width"), QString::number(naxes[0])});
|
||||||
info.info.append({QObject::tr("Height"), QString::number(naxes[1])});
|
info.info.append({QObject::tr("Height"), QString::number(naxes[1])});
|
||||||
|
|
||||||
|
RawImage img(w, h, naxis == 2 ? 1 : naxes[2], type);
|
||||||
|
uint8_t *data = static_cast<uint8_t*>(img.data());
|
||||||
for (int i=1; i==1 || i<=naxes[2]; i++)
|
for (int i=1; i==1 || i<=naxes[2]; i++)
|
||||||
{
|
{
|
||||||
cv::Mat tmp(h, w, cvtype);
|
|
||||||
fpixel[2] = i;
|
fpixel[2] = i;
|
||||||
fits_read_pix(file, fitstype, fpixel, size, NULL, tmp.ptr(), NULL, &status);
|
fits_read_pix(file, fitstype, fpixel, size, NULL, data + img.size() * RawImage::typeSize(type) * (i-1), NULL, &status);
|
||||||
if(cvtype == CV_16S)
|
}
|
||||||
tmp.convertTo(tmp, CV_16U, 1, 32767);
|
if(fitstype == TSHORT)
|
||||||
cvimg.push_back(tmp);
|
{
|
||||||
|
uint16_t *s = static_cast<uint16_t*>(img.data());
|
||||||
|
size_t size = img.size() * img.channels();
|
||||||
|
for(size_t i=0; i<size; i++)
|
||||||
|
s[i] -= INT16_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cvimg.size() == 1)
|
if(img.channels() == 1)
|
||||||
{
|
*image = new RawImage(std::move(img));
|
||||||
*image = new RawImage(cvimg[0]);
|
else
|
||||||
}
|
*image = RawImage::fromPlanar(img);
|
||||||
if(cvimg.size() == 3)
|
|
||||||
{
|
if(*image)
|
||||||
cv::Mat rgb;
|
(*image)->convertToGLFormat();
|
||||||
cv::merge(cvimg, rgb);
|
|
||||||
*image = new RawImage(rgb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
noload:
|
noload:
|
||||||
@@ -310,51 +319,33 @@ bool loadXISF(const QString &path, ImageInfoData &info, RawImage **image)
|
|||||||
info.info.append({QObject::tr("Height"), QString::number(xisfImage.height())});
|
info.info.append({QObject::tr("Height"), QString::number(xisfImage.height())});
|
||||||
if(!info.wcs->valid())info.wcs.reset();
|
if(!info.wcs->valid())info.wcs.reset();
|
||||||
|
|
||||||
|
RawImage::DataType type;
|
||||||
|
switch(xisfImage.sampleFormat())
|
||||||
|
{
|
||||||
|
case LibXISF::Image::UInt8: type = RawImage::UINT8; break;
|
||||||
|
case LibXISF::Image::UInt16: type = RawImage::UINT16; break;
|
||||||
|
case LibXISF::Image::UInt32: type = RawImage::UINT32; break;
|
||||||
|
case LibXISF::Image::Float32: type = RawImage::FLOAT32; break;
|
||||||
|
case LibXISF::Image::Float64: type = RawImage::FLOAT64; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
if(xisfImage.channelCount() == 1)
|
if(xisfImage.channelCount() == 1)
|
||||||
{
|
{
|
||||||
switch(xisfImage.sampleFormat())
|
*image = new RawImage(xisfImage.width(), xisfImage.height(), 1, type);
|
||||||
{
|
std::memcpy((*image)->data(), xisfImage.imageData(), xisfImage.imageDataSize());
|
||||||
case LibXISF::Image::UInt8:
|
|
||||||
*image = new RawImage(xisfImage.width(), xisfImage.height(), RawImage::UINT8);
|
|
||||||
std::memcpy((*image)->data(), xisfImage.imageData(), xisfImage.imageDataSize());
|
|
||||||
break;
|
|
||||||
case LibXISF::Image::UInt16:
|
|
||||||
*image = new RawImage(xisfImage.width(), xisfImage.height(), RawImage::UINT16);
|
|
||||||
std::memcpy((*image)->data(), xisfImage.imageData(), xisfImage.imageDataSize());
|
|
||||||
break;
|
|
||||||
case LibXISF::Image::Float32:
|
|
||||||
*image = new RawImage(xisfImage.width(), xisfImage.height(), RawImage::FLOAT32);
|
|
||||||
std::memcpy((*image)->data(), xisfImage.imageData(), xisfImage.imageDataSize());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(xisfImage.channelCount() == 3)
|
else if(xisfImage.channelCount() == 3 || xisfImage.channelCount() == 4)
|
||||||
{
|
{
|
||||||
LibXISF::Image tmpImage = xisfImage;
|
LibXISF::Image tmpImage = xisfImage;
|
||||||
tmpImage.convertPixelStorageTo(LibXISF::Image::Normal);
|
tmpImage.convertPixelStorageTo(LibXISF::Image::Planar);
|
||||||
|
*image = RawImage::fromPlanar(tmpImage.imageData(), tmpImage.width(), tmpImage.height(), tmpImage.channelCount(), type);
|
||||||
switch(tmpImage.sampleFormat())
|
|
||||||
{
|
|
||||||
case LibXISF::Image::UInt8:
|
|
||||||
*image = new RawImage(tmpImage.width(), tmpImage.height(), RawImage::UINT8C3);
|
|
||||||
std::memcpy((*image)->data(), tmpImage.imageData(), tmpImage.imageDataSize());
|
|
||||||
break;
|
|
||||||
case LibXISF::Image::UInt16:
|
|
||||||
*image = new RawImage(tmpImage.width(), tmpImage.height(), RawImage::UINT16C3);
|
|
||||||
std::memcpy((*image)->data(), tmpImage.imageData(), tmpImage.imageDataSize());
|
|
||||||
break;
|
|
||||||
case LibXISF::Image::Float32:
|
|
||||||
*image = new RawImage(tmpImage.width(), tmpImage.height(), RawImage::FLOAT32C3);
|
|
||||||
std::memcpy((*image)->data(), tmpImage.imageData(), tmpImage.imageDataSize());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(*image)
|
if(*image)
|
||||||
|
{
|
||||||
|
(*image)->convertToGLFormat();
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (LibXISF::Error &err)
|
catch (LibXISF::Error &err)
|
||||||
{
|
{
|
||||||
@@ -439,11 +430,7 @@ void LoadRunable::run()
|
|||||||
if(m_analyzeLevel >= Peaks)
|
if(m_analyzeLevel >= Peaks)
|
||||||
{
|
{
|
||||||
std::vector<Peak> peaks;
|
std::vector<Peak> peaks;
|
||||||
if(raw) {
|
/*RawImage *medianImage = rawImage->medianFilter();
|
||||||
rawImage->quarter();
|
|
||||||
qDebug() << "quarter" << timer.restart();
|
|
||||||
}
|
|
||||||
RawImage *medianImage = rawImage->medianFilter();
|
|
||||||
qDebug() << "median" << timer.restart();
|
qDebug() << "median" << timer.restart();
|
||||||
int numPeaks = medianImage->findPeaks(median+stdDev*2, 20, peaks);
|
int numPeaks = medianImage->findPeaks(median+stdDev*2, 20, peaks);
|
||||||
delete medianImage;
|
delete medianImage;
|
||||||
@@ -483,7 +470,7 @@ void LoadRunable::run()
|
|||||||
info.info.append({QObject::tr("FWHM X"), QString::number(fwhmX/stars.size())});
|
info.info.append({QObject::tr("FWHM X"), QString::number(fwhmX/stars.size())});
|
||||||
info.info.append({QObject::tr("FWHM Y"), QString::number(fwhmY/stars.size())});
|
info.info.append({QObject::tr("FWHM Y"), QString::number(fwhmY/stars.size())});
|
||||||
}
|
}
|
||||||
qDebug() << "Star fit" << timer.restart();
|
qDebug() << "Star fit" << timer.restart();*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,10 +485,6 @@ void LoadRunable::run()
|
|||||||
else
|
else
|
||||||
QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(void*, rawImage), Q_ARG(ImageInfoData, info));
|
QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(void*, rawImage), Q_ARG(ImageInfoData, info));
|
||||||
}
|
}
|
||||||
catch(cv::Exception e)
|
|
||||||
{
|
|
||||||
qDebug() << e.what();
|
|
||||||
}
|
|
||||||
catch(std::exception e)
|
catch(std::exception e)
|
||||||
{
|
{
|
||||||
qDebug() << e.what();
|
qDebug() << e.what();
|
||||||
@@ -566,40 +549,40 @@ void writeFITSImage(fitsfile *fw, RawImage *rawimage, ImageInfoData &imageinfo)
|
|||||||
int status = 0;
|
int status = 0;
|
||||||
long firstpix[3] = {1,1,1};
|
long firstpix[3] = {1,1,1};
|
||||||
|
|
||||||
int channels = rawimage->mat().channels();
|
int channels = rawimage->channels();
|
||||||
int naxis = channels == 1 ? 2 : 3;
|
int naxis = channels == 1 ? 2 : 3;
|
||||||
long naxes[3] = {(int)rawimage->width(), (int)rawimage->height(), rawimage->mat().channels()};
|
long naxes[3] = {(int)rawimage->width(), (int)rawimage->height(), rawimage->channels()};
|
||||||
|
|
||||||
std::vector<cv::Mat> mat;
|
std::vector<RawImage> planes;
|
||||||
if(channels == 1)
|
if(channels == 1)
|
||||||
mat.push_back(rawimage->mat());
|
planes.push_back(*rawimage);
|
||||||
else
|
else
|
||||||
cv::split(rawimage->mat(), mat);
|
planes = rawimage->split();
|
||||||
|
|
||||||
switch(CV_MAT_DEPTH(rawimage->dataType()))
|
switch(rawimage->type())
|
||||||
{
|
{
|
||||||
case CV_8U:
|
case RawImage::UINT8:
|
||||||
fits_create_img(fw, BYTE_IMG, naxis, naxes, &status);
|
fits_create_img(fw, BYTE_IMG, naxis, naxes, &status);
|
||||||
for(int i=0; i<channels; i++)
|
for(int i=0; i<channels; i++)
|
||||||
{
|
{
|
||||||
firstpix[2] = i+1;
|
firstpix[2] = i+1;
|
||||||
fits_write_pix(fw, TBYTE, firstpix, rawimage->size(), mat[i].data, &status);
|
fits_write_pix(fw, TBYTE, firstpix, rawimage->size(), planes[i].data(), &status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CV_16U:
|
case RawImage::UINT16:
|
||||||
fits_create_img(fw, USHORT_IMG, naxis, naxes, &status);
|
fits_create_img(fw, USHORT_IMG, naxis, naxes, &status);
|
||||||
for(int i=0; i<channels; i++)
|
for(int i=0; i<channels; i++)
|
||||||
{
|
{
|
||||||
firstpix[2] = i+1;
|
firstpix[2] = i+1;
|
||||||
fits_write_pix(fw, TUSHORT, firstpix, rawimage->size(), mat[i].data, &status);
|
fits_write_pix(fw, TUSHORT, firstpix, rawimage->size(), planes[i].data(), &status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CV_32F:
|
case RawImage::FLOAT32:
|
||||||
fits_create_img(fw, FLOAT_IMG, naxis, naxes, &status);
|
fits_create_img(fw, FLOAT_IMG, naxis, naxes, &status);
|
||||||
for(int i=0; i<channels; i++)
|
for(int i=0; i<channels; i++)
|
||||||
{
|
{
|
||||||
firstpix[2] = i+1;
|
firstpix[2] = i+1;
|
||||||
fits_write_pix(fw, TFLOAT, firstpix, rawimage->size(), mat[i].data, &status);
|
fits_write_pix(fw, TFLOAT, firstpix, rawimage->size(), planes[i].data(), &status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -645,13 +628,13 @@ void ConvertRunable::run()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
LibXISF::XISFWriter xisf;
|
LibXISF::XISFWriter xisf;
|
||||||
int channelCount = rawimage->mat().channels();
|
int channelCount = rawimage->channels();
|
||||||
LibXISF::Image::SampleFormat sampleFormat;
|
LibXISF::Image::SampleFormat sampleFormat;
|
||||||
switch(CV_MAT_DEPTH(rawimage->dataType()))
|
switch(rawimage->type())
|
||||||
{
|
{
|
||||||
case CV_8U: sampleFormat = LibXISF::Image::UInt8; break;
|
case RawImage::UINT8: sampleFormat = LibXISF::Image::UInt8; break;
|
||||||
case CV_16U: sampleFormat = LibXISF::Image::UInt16; break;
|
case RawImage::UINT16: sampleFormat = LibXISF::Image::UInt16; break;
|
||||||
case CV_32F: sampleFormat = LibXISF::Image::Float32; break;
|
case RawImage::FLOAT32: sampleFormat = LibXISF::Image::Float32; break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+308
-178
@@ -1,142 +1,129 @@
|
|||||||
#include "rawimage.h"
|
#include "rawimage.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
int THUMB_SIZE = 128;
|
int THUMB_SIZE = 128;
|
||||||
int THUMB_SIZE_BORDER = 138;
|
int THUMB_SIZE_BORDER = 138;
|
||||||
int THUMB_SIZE_BORDER_Y = 158;
|
int THUMB_SIZE_BORDER_Y = 158;
|
||||||
double SATURATION = 0.95;
|
double SATURATION = 0.95;
|
||||||
|
|
||||||
RawImage::ImgType CV2Type(int cvtype)
|
size_t RawImage::typeSize(RawImage::DataType type)
|
||||||
{
|
{
|
||||||
switch (cvtype)
|
switch(type)
|
||||||
{
|
{
|
||||||
case CV_8U:
|
case RawImage::UINT8:
|
||||||
return RawImage::UINT8;
|
return 1;
|
||||||
case CV_16U:
|
case RawImage::UINT16:
|
||||||
return RawImage::UINT16;
|
return 2;
|
||||||
case CV_32F:
|
case RawImage::UINT32:
|
||||||
return RawImage::FLOAT32;
|
case RawImage::FLOAT32:
|
||||||
case CV_8UC3:
|
return 4;
|
||||||
return RawImage::UINT8C3;
|
case RawImage::FLOAT64:
|
||||||
case CV_8UC4:
|
return 8;
|
||||||
return RawImage::UINT8C4;
|
default: return 1;
|
||||||
case CV_16UC3:
|
|
||||||
return RawImage::UINT16C3;
|
|
||||||
case CV_16UC4:
|
|
||||||
return RawImage::UINT16C4;
|
|
||||||
case CV_32FC3:
|
|
||||||
return RawImage::FLOAT32C3;
|
|
||||||
default:
|
|
||||||
return RawImage::UNKNOWN;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Type2CV(RawImage::ImgType type)
|
void RawImage::allocate(uint32_t w, uint32_t h, uint32_t ch, DataType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
m_width = w;
|
||||||
{
|
m_height = h;
|
||||||
case RawImage::UINT8:
|
m_channels = ch;
|
||||||
return CV_8U;
|
m_ch = ch == 3 ? 4 : ch;
|
||||||
case RawImage::UINT16:
|
m_origType = m_type = type;
|
||||||
return CV_16U;
|
m_pixels.reset(new PixelType[m_width * m_height * m_ch * typeSize(type)]);
|
||||||
case RawImage::FLOAT32:
|
|
||||||
return CV_32F;
|
|
||||||
case RawImage::UINT8C3:
|
|
||||||
return CV_8UC3;
|
|
||||||
case RawImage::UINT8C4:
|
|
||||||
return CV_8UC4;
|
|
||||||
case RawImage::UINT16C3:
|
|
||||||
return CV_16UC3;
|
|
||||||
case RawImage::UINT16C4:
|
|
||||||
return CV_16UC4;
|
|
||||||
case RawImage::FLOAT32C3:
|
|
||||||
return CV_32FC3;
|
|
||||||
case RawImage::UNKNOWN:
|
|
||||||
return CV_8S;
|
|
||||||
default:
|
|
||||||
return CV_8U;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RawImage::RawImage()
|
RawImage::RawImage()
|
||||||
{
|
{
|
||||||
m_stats = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RawImage::RawImage(int w, int h, ImgType type)
|
RawImage::RawImage(uint32_t w, uint32_t h, uint32_t ch, DataType type)
|
||||||
{
|
{
|
||||||
m_img.create(h, w, Type2CV(type));
|
allocate(w, h, ch, type);
|
||||||
m_stats = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RawImage::RawImage(cv::Mat &img)
|
|
||||||
{
|
|
||||||
m_img = img;
|
|
||||||
m_stats = false;
|
|
||||||
scaleToUnit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RawImage::RawImage(const RawImage &d)
|
RawImage::RawImage(const RawImage &d)
|
||||||
{
|
{
|
||||||
d.m_img.copyTo(m_img);
|
allocate(d.m_width, d.m_height, d.m_channels, d.m_type);
|
||||||
m_mean = d.m_mean;
|
std::memcpy(m_pixels.get(), d.m_pixels.get(), m_width * m_height * m_ch * typeSize(m_type));
|
||||||
m_stdDev = d.m_stdDev;
|
|
||||||
m_median = d.m_median;
|
|
||||||
m_min = d.m_min;
|
|
||||||
m_max = d.m_max;
|
|
||||||
m_mad = d.m_mad;
|
|
||||||
m_stats = d.m_stats;
|
m_stats = d.m_stats;
|
||||||
m_saturated = d.m_saturated;
|
m_saturated = d.m_saturated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawImage::RawImage(RawImage &&d)
|
||||||
|
{
|
||||||
|
m_pixels = std::move(d.m_pixels);
|
||||||
|
m_original = std::move(d.m_original);
|
||||||
|
m_width = d.m_width;
|
||||||
|
m_height = d.m_height;
|
||||||
|
m_channels = d.m_channels;
|
||||||
|
m_ch = d.m_ch;
|
||||||
|
m_type = d.m_type;
|
||||||
|
m_origType = d.m_origType;
|
||||||
|
m_stats = d.m_stats;
|
||||||
|
m_thumbAspect = d.m_thumbAspect;
|
||||||
|
m_saturated = d.m_saturated;
|
||||||
|
}
|
||||||
|
|
||||||
RawImage::RawImage(const QImage &img)
|
RawImage::RawImage(const QImage &img)
|
||||||
{
|
{
|
||||||
if(img.format() == QImage::Format_RGB32)
|
qDebug() << img;
|
||||||
|
if(img.format() == QImage::Format_RGBX8888)
|
||||||
{
|
{
|
||||||
m_img.create(img.height(), img.width(), CV_8UC4);
|
allocate(img.width(), img.height(), 3, UINT8);
|
||||||
for(int i=0; i<img.height(); i++)
|
for(int i=0; i<img.height(); i++)
|
||||||
std::memcpy(m_img.ptr(i), img.scanLine(i), img.width()*4);
|
std::memcpy(data(i), img.scanLine(i), img.width()*4);
|
||||||
cv::cvtColor(m_img, m_img, cv::COLOR_BGRA2RGB);
|
|
||||||
}
|
}
|
||||||
else if(img.format() == QImage::Format_ARGB32)
|
else if(img.format() == QImage::Format_RGBA8888)
|
||||||
{
|
{
|
||||||
m_img.create(img.height(), img.width(), CV_8UC4);
|
allocate(img.width(), img.height(), 4, UINT8);
|
||||||
for(int i=0; i<img.height(); i++)
|
for(int i=0; i<img.height(); i++)
|
||||||
std::memcpy(m_img.ptr(i), img.scanLine(i), img.width()*4);
|
std::memcpy(data(i), img.scanLine(i), img.width()*4);
|
||||||
cv::cvtColor(m_img, m_img, cv::COLOR_BGRA2RGBA);
|
|
||||||
}
|
}
|
||||||
else if(img.format() == QImage::Format_RGBX64)
|
else if(img.format() == QImage::Format_RGBX64)
|
||||||
{
|
{
|
||||||
m_img.create(img.height(), img.width(), CV_16UC4);
|
allocate(img.width(), img.height(), 3, UINT16);
|
||||||
for(int i=0; i<img.height(); i++)
|
for(int i=0; i<img.height(); i++)
|
||||||
std::memcpy(m_img.ptr(i), img.scanLine(i), img.width()*8);
|
std::memcpy(data(i), img.scanLine(i), img.width()*8);
|
||||||
cv::cvtColor(m_img, m_img, cv::COLOR_RGBA2RGB);
|
|
||||||
}
|
}
|
||||||
else if(img.format() == QImage::Format_RGBA64)
|
else if(img.format() == QImage::Format_RGBA64)
|
||||||
{
|
{
|
||||||
m_img.create(img.height(), img.width(), CV_16UC4);
|
allocate(img.width(), img.height(), 4, UINT16);
|
||||||
for(int i=0; i<img.height(); i++)
|
for(int i=0; i<img.height(); i++)
|
||||||
std::memcpy(m_img.ptr(i), img.scanLine(i), img.width()*8);
|
std::memcpy(data(i), img.scanLine(i), img.width()*8);
|
||||||
|
}
|
||||||
|
else if(img.format() == QImage::Format_Grayscale8)
|
||||||
|
{
|
||||||
|
allocate(img.width(), img.height(), 1, UINT8);
|
||||||
|
for(int i=0; i<img.height(); i++)
|
||||||
|
std::memcpy(data(i), img.scanLine(i), img.width());
|
||||||
|
}
|
||||||
|
else if(img.format() == QImage::Format_Grayscale16)
|
||||||
|
{
|
||||||
|
allocate(img.width(), img.height(), 1, UINT16);
|
||||||
|
for(int i=0; i<img.height(); i++)
|
||||||
|
std::memcpy(data(i), img.scanLine(i), img.width()*2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QImage tmp = img.convertToFormat(QImage::Format_RGB888);
|
QImage tmp = img.convertToFormat(QImage::Format_RGBA8888);
|
||||||
m_img.create(img.height(), img.width(), CV_8UC3);
|
allocate(img.width(), img.height(), 4, UINT8);
|
||||||
|
|
||||||
for(int i=0; i<tmp.height(); i++)
|
for(int i=0; i<tmp.height(); i++)
|
||||||
std::memcpy(m_img.ptr(i), tmp.scanLine(i), tmp.width()*3);
|
std::memcpy(data(i), tmp.scanLine(i), tmp.width()*4);
|
||||||
}
|
}
|
||||||
m_stats = false;
|
m_stats.m_stats = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RawImage::imageStats(double *mean, double *stdDev, double *median, double *min, double *max, double *mad, uint32_t *saturated)
|
bool RawImage::imageStats(double *mean, double *stdDev, double *median, double *min, double *max, double *mad, uint32_t *saturated)
|
||||||
{
|
{
|
||||||
if(!m_stats)calcStats();
|
if(!m_stats.m_stats)calcStats();
|
||||||
if(mean)*mean = m_mean;
|
if(mean)*mean = m_stats.m_mean[0];
|
||||||
if(stdDev)*stdDev = m_stdDev;
|
if(stdDev)*stdDev = m_stats.m_stdDev[0];
|
||||||
if(median)*median = m_median;
|
if(median)*median = m_stats.m_median[0];
|
||||||
if(min)*min = m_min;
|
if(min)*min = m_stats.m_min[0];
|
||||||
if(max)*max = m_max;
|
if(max)*max = m_stats.m_max[0];
|
||||||
if(mad)*mad = m_mad;
|
if(mad)*mad = m_stats.m_mad[0];
|
||||||
if(saturated)*saturated = m_saturated;
|
if(saturated)*saturated = m_saturated;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -144,10 +131,10 @@ bool RawImage::imageStats(double *mean, double *stdDev, double *median, double *
|
|||||||
|
|
||||||
void RawImage::calcStats()
|
void RawImage::calcStats()
|
||||||
{
|
{
|
||||||
if(m_stats)return;
|
if(m_stats.m_stats)return;
|
||||||
m_stats = true;
|
m_stats.m_stats = true;
|
||||||
|
|
||||||
cv::Scalar meanS, stdDevS;
|
/*cv::Scalar meanS, stdDevS;
|
||||||
|
|
||||||
cv::meanStdDev(m_img, meanS, stdDevS);
|
cv::meanStdDev(m_img, meanS, stdDevS);
|
||||||
cv::minMaxIdx(m_img, &m_min, &m_max);
|
cv::minMaxIdx(m_img, &m_min, &m_max);
|
||||||
@@ -200,12 +187,12 @@ void RawImage::calcStats()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(img.type() == CV_32F)m_mad /= histSize;
|
if(img.type() == CV_32F)m_mad /= histSize;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawImage::rect(int &x, int &y, int w, int h, std::vector<double> &r) const
|
void RawImage::rect(int &x, int &y, int w, int h, std::vector<double> &r) const
|
||||||
{
|
{
|
||||||
r.resize(w*h);
|
/*r.resize(w*h);
|
||||||
x -= w/2;
|
x -= w/2;
|
||||||
y -= h/2;
|
y -= h/2;
|
||||||
if(x<0)x = 0;
|
if(x<0)x = 0;
|
||||||
@@ -215,12 +202,12 @@ void RawImage::rect(int &x, int &y, int w, int h, std::vector<double> &r) const
|
|||||||
cv::Mat roiImg(m_img, cv::Rect(x, y, w, h));
|
cv::Mat roiImg(m_img, cv::Rect(x, y, w, h));
|
||||||
cv::Mat doubleMat;
|
cv::Mat doubleMat;
|
||||||
roiImg.convertTo(doubleMat, CV_64F);
|
roiImg.convertTo(doubleMat, CV_64F);
|
||||||
r = std::vector<double>(doubleMat.begin<double>(), doubleMat.end<double>());
|
r = std::vector<double>(doubleMat.begin<double>(), doubleMat.end<double>());*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int RawImage::findPeaks(double background, double distance, std::vector<Peak> &peaks) const
|
int RawImage::findPeaks(double background, double distance, std::vector<Peak> &peaks) const
|
||||||
{
|
{
|
||||||
std::vector<std::vector<cv::Point>> contours;
|
/*std::vector<std::vector<cv::Point>> contours;
|
||||||
|
|
||||||
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(distance, distance));
|
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(distance, distance));
|
||||||
|
|
||||||
@@ -240,29 +227,22 @@ int RawImage::findPeaks(double background, double distance, std::vector<Peak> &p
|
|||||||
peaks.push_back(Peak(1, contour[0].x, contour[0].y));
|
peaks.push_back(Peak(1, contour[0].x, contour[0].y));
|
||||||
}
|
}
|
||||||
|
|
||||||
return peaks.size();
|
return peaks.size();*/
|
||||||
}
|
|
||||||
|
|
||||||
RawImage* RawImage::medianFilter() const
|
|
||||||
{
|
|
||||||
RawImage *ret = new RawImage();
|
|
||||||
cv::medianBlur(m_img, ret->m_img, 3);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RawImage::quarter()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RawImage::width() const
|
uint32_t RawImage::width() const
|
||||||
{
|
{
|
||||||
return m_img.cols;
|
return m_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RawImage::height() const
|
uint32_t RawImage::height() const
|
||||||
{
|
{
|
||||||
return m_img.rows;
|
return m_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RawImage::channels() const
|
||||||
|
{
|
||||||
|
return m_channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RawImage::size() const
|
uint32_t RawImage::size() const
|
||||||
@@ -270,27 +250,21 @@ uint32_t RawImage::size() const
|
|||||||
return width()*height();
|
return width()*height();
|
||||||
}
|
}
|
||||||
|
|
||||||
RawImage::ImgType RawImage::type() const
|
RawImage::DataType RawImage::type() const
|
||||||
{
|
{
|
||||||
return CV2Type(m_img.type());
|
return m_type;
|
||||||
}
|
|
||||||
|
|
||||||
int RawImage::dataType() const
|
|
||||||
{
|
|
||||||
return m_img.type();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RawImage::norm() const
|
uint32_t RawImage::norm() const
|
||||||
{
|
{
|
||||||
switch(m_img.type())
|
switch(m_type)
|
||||||
{
|
{
|
||||||
case CV_8U:
|
case UINT8:
|
||||||
case CV_8UC3:
|
|
||||||
case CV_8UC4:
|
|
||||||
return UINT8_MAX;
|
return UINT8_MAX;
|
||||||
case CV_16U:
|
case UINT16:
|
||||||
case CV_16UC3:
|
|
||||||
return UINT16_MAX;
|
return UINT16_MAX;
|
||||||
|
case UINT32:
|
||||||
|
return UINT32_MAX;
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -298,37 +272,113 @@ uint32_t RawImage::norm() const
|
|||||||
|
|
||||||
void* RawImage::data()
|
void* RawImage::data()
|
||||||
{
|
{
|
||||||
return m_img.ptr();
|
return m_pixels.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *RawImage::data() const
|
const void *RawImage::data() const
|
||||||
{
|
{
|
||||||
return m_img.ptr();
|
return m_pixels.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *RawImage::data(uint32_t row, uint32_t col)
|
||||||
|
{
|
||||||
|
return m_pixels.get() + (m_width * row * m_ch + col * m_ch) * typeSize(m_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *RawImage::data(uint32_t row, uint32_t col) const
|
||||||
|
{
|
||||||
|
return m_pixels.get() + (m_width * row * m_ch + col * m_ch) * typeSize(m_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *RawImage::origData(uint32_t row, uint32_t col) const
|
||||||
|
{
|
||||||
|
if(m_original)
|
||||||
|
return m_original.get() + (m_width * row * m_ch + col * m_ch) * typeSize(m_origType);
|
||||||
|
else
|
||||||
|
return m_pixels.get() + (m_width * row * m_ch + col * m_ch) * typeSize(m_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawImage::convertToThumbnail()
|
void RawImage::convertToThumbnail()
|
||||||
{
|
{
|
||||||
m_thumbAspect = (float)width() / height();
|
m_thumbAspect = (float)width() / height();
|
||||||
switch(CV_MAT_DEPTH(m_img.type()))
|
uint16_t *out = reinterpret_cast<uint16_t*>(new uint8_t[THUMB_SIZE * THUMB_SIZE * 4 * sizeof(uint16_t)]);
|
||||||
|
|
||||||
|
auto loop = [&](uint16_t *out, auto *in, auto scale)
|
||||||
{
|
{
|
||||||
case CV_8U:
|
for(int i=0; i<THUMB_SIZE; i++)
|
||||||
m_img.convertTo(m_img, CV_16U, 255);
|
{
|
||||||
|
for(int o=0; o<THUMB_SIZE; o++)
|
||||||
|
{
|
||||||
|
int idx = (i*THUMB_SIZE + o)*4;
|
||||||
|
int idx2 = ((i * m_height / THUMB_SIZE * m_width) + (o * m_width / THUMB_SIZE)) * m_ch;
|
||||||
|
if(m_channels == 1)
|
||||||
|
{
|
||||||
|
out[idx] = out[idx + 1] = out[idx + 2] = in[idx2] * scale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[idx] = in[idx2] * scale;;
|
||||||
|
out[idx + 1] = in[idx2 + 1] * scale;;
|
||||||
|
out[idx + 2] = in[idx2 + 2] * scale;;
|
||||||
|
}
|
||||||
|
out[idx + 3] = UINT16_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(m_type)
|
||||||
|
{
|
||||||
|
case UINT8:
|
||||||
|
loop(out, reinterpret_cast<uint8_t*>(m_pixels.get()), 256);
|
||||||
break;
|
break;
|
||||||
case CV_32F:
|
case UINT16:
|
||||||
m_img.convertTo(m_img, CV_16U, 65535);
|
loop(out, reinterpret_cast<uint16_t*>(m_pixels.get()), 1);
|
||||||
break;
|
break;
|
||||||
case CV_16U:
|
case UINT32:
|
||||||
|
loop(out, reinterpret_cast<uint32_t*>(m_pixels.get()), UINT16_MAX/(float)UINT32_MAX);
|
||||||
|
break;
|
||||||
|
case FLOAT32:
|
||||||
|
loop(out, reinterpret_cast<float*>(m_pixels.get()), 65535.0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
qDebug() << "Should not happend";
|
||||||
|
delete [] out;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_img.channels() == 1)
|
m_pixels.reset(reinterpret_cast<uint8_t*>(out));
|
||||||
cv::cvtColor(m_img, m_img, cv::COLOR_GRAY2RGB);
|
m_width = THUMB_SIZE;
|
||||||
if(m_img.channels() == 4)
|
m_height = THUMB_SIZE;
|
||||||
cv::cvtColor(m_img, m_img, cv::COLOR_RGBA2RGB);
|
m_ch = 4;
|
||||||
cv::Size dsize(THUMB_SIZE, THUMB_SIZE);
|
m_channels = 3;
|
||||||
cv::resize(m_img, m_img, dsize, 0, 0, cv::INTER_NEAREST);
|
m_type = UINT16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawImage::convertToGLFormat()
|
||||||
|
{
|
||||||
|
size_t s = size() * m_ch;
|
||||||
|
if(m_type == UINT32)
|
||||||
|
{
|
||||||
|
m_original = std::move(m_pixels);
|
||||||
|
allocate(m_width, m_height, m_channels, FLOAT32);
|
||||||
|
m_origType = UINT32;
|
||||||
|
float *dst = reinterpret_cast<float*>(m_pixels.get());
|
||||||
|
uint32_t *src = reinterpret_cast<uint32_t*>(m_original.get());
|
||||||
|
|
||||||
|
for(size_t i = 0; i < s; i++)
|
||||||
|
dst[i] = src[i] / (float)UINT32_MAX;
|
||||||
|
}
|
||||||
|
else if(m_type == FLOAT64)
|
||||||
|
{
|
||||||
|
m_original = std::move(m_pixels);
|
||||||
|
allocate(m_width, m_height, m_channels, FLOAT32);
|
||||||
|
m_origType = FLOAT64;
|
||||||
|
float *dst = reinterpret_cast<float*>(m_pixels.get());
|
||||||
|
double *src = reinterpret_cast<double*>(m_original.get());
|
||||||
|
|
||||||
|
for(size_t i = 0; i < s; i++)
|
||||||
|
dst[i] = src[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float RawImage::thumbAspect() const
|
float RawImage::thumbAspect() const
|
||||||
@@ -336,69 +386,94 @@ float RawImage::thumbAspect() const
|
|||||||
return m_thumbAspect;
|
return m_thumbAspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cv::Mat& RawImage::mat() const
|
bool RawImage::pixel(int x, int y, double &r, double &g, double &b) const
|
||||||
{
|
|
||||||
return m_img;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RawImage::pixel(int x, int y, QVector3D &rgb) const
|
|
||||||
{
|
{
|
||||||
if(x < 0 || y < 0 || x >= (int)width() || y >= (int)height())return false;
|
if(x < 0 || y < 0 || x >= (int)width() || y >= (int)height())return false;
|
||||||
|
|
||||||
switch(m_img.type())
|
switch(m_origType)
|
||||||
{
|
{
|
||||||
case CV_8U:
|
case UINT8:
|
||||||
{
|
{
|
||||||
uint8_t v = m_img.at<uint8_t>(y, x);
|
const uint8_t *v = static_cast<const uint8_t*>(origData(y, x));
|
||||||
rgb = QVector3D(v, v, v);
|
if(m_channels == 1)
|
||||||
|
{
|
||||||
|
r = g = b = *v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = v[0];
|
||||||
|
g = v[1];
|
||||||
|
b = v[2];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CV_16U:
|
case UINT16:
|
||||||
{
|
{
|
||||||
uint16_t v = m_img.at<uint16_t>(y, x);
|
const uint16_t *v = static_cast<const uint16_t*>(origData(y, x));
|
||||||
rgb = QVector3D(v, v, v);
|
if(m_channels == 1)
|
||||||
|
{
|
||||||
|
r = g = b = *v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = v[0];
|
||||||
|
g = v[1];
|
||||||
|
b = v[2];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CV_32F:
|
case UINT32:
|
||||||
{
|
{
|
||||||
float v = m_img.at<float>(y, x);
|
const uint32_t *v = static_cast<const uint32_t*>(origData(y, x));
|
||||||
rgb = QVector3D(v, v, v);
|
if(m_channels == 1)
|
||||||
|
{
|
||||||
|
r = g = b = *v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = v[0];
|
||||||
|
g = v[1];
|
||||||
|
b = v[2];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CV_8UC3:
|
case FLOAT32:
|
||||||
{
|
{
|
||||||
cv::Vec3b v = m_img.at<cv::Vec3b>(y, x);
|
const float *v = static_cast<const float*>(origData(y, x));
|
||||||
rgb = QVector3D(v[0], v[1], v[2]);
|
if(m_channels == 1)
|
||||||
|
{
|
||||||
|
r = g = b = *v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = v[0];
|
||||||
|
g = v[1];
|
||||||
|
b = v[2];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CV_8UC4:
|
case FLOAT64:
|
||||||
{
|
{
|
||||||
cv::Vec4b v = m_img.at<cv::Vec4b>(y, x);
|
const double *v = static_cast<const double*>(origData(y, x));
|
||||||
rgb = QVector3D(v[0], v[1], v[2]);
|
if(m_channels == 1)
|
||||||
|
{
|
||||||
|
r = g = b = *v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = v[0];
|
||||||
|
g = v[1];
|
||||||
|
b = v[2];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CV_16UC3:
|
|
||||||
{
|
|
||||||
cv::Vec3w v = m_img.at<cv::Vec3w>(y, x);
|
|
||||||
rgb = QVector3D(v[0], v[1], v[2]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CV_32FC3:
|
|
||||||
{
|
|
||||||
cv::Vec3f v = m_img.at<cv::Vec3f>(y, x);
|
|
||||||
rgb = QVector3D(v[0], v[1], v[2]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
rgb = QVector3D(0, 0, 0);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawImage::scaleToUnit()
|
void RawImage::scaleToUnit()
|
||||||
{
|
{
|
||||||
if(CV_MAT_DEPTH(m_img.type()) == CV_32F)
|
/*if(CV_MAT_DEPTH(m_img.type()) == CV_32F)
|
||||||
{
|
{
|
||||||
double min, max;
|
double min, max;
|
||||||
cv::minMaxIdx(m_img, &min, &max);
|
cv::minMaxIdx(m_img, &min, &max);
|
||||||
@@ -408,15 +483,70 @@ void RawImage::scaleToUnit()
|
|||||||
float zero = min * scale;
|
float zero = min * scale;
|
||||||
m_img = m_img * scale - zero;
|
m_img = m_img * scale - zero;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawImage::downscaleTo(uint32_t size)
|
void RawImage::downscaleTo(uint32_t size)
|
||||||
{
|
{
|
||||||
if(size < width() || size < height())
|
/*if(size < width() || size < height())
|
||||||
{
|
{
|
||||||
double s = (double)size / std::max(width(), height());
|
double s = (double)size / std::max(width(), height());
|
||||||
cv::Size dsize(std::floor(width() * s), std::floor(height() * s));
|
cv::Size dsize(std::floor(width() * s), std::floor(height() * s));
|
||||||
cv::resize(m_img, m_img, dsize, 0, 0, cv::INTER_AREA);
|
cv::resize(m_img, m_img, dsize, 0, 0, cv::INTER_AREA);
|
||||||
}
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
RawImage *RawImage::fromPlanar(const RawImage &img)
|
||||||
|
{
|
||||||
|
return RawImage::fromPlanar(img.data(), img.width(), img.height(), img.channels(), img.type());
|
||||||
|
}
|
||||||
|
|
||||||
|
RawImage *RawImage::fromPlanar(const void *pixels, uint32_t w, uint32_t h, uint32_t ch, RawImage::DataType type)
|
||||||
|
{
|
||||||
|
RawImage *image = new RawImage(w, h, ch, type);
|
||||||
|
size_t size = w * h;
|
||||||
|
size_t ch2 = ch == 1 ? 1 : 4;
|
||||||
|
auto convert = [&](auto *in, auto *out, auto alpha)
|
||||||
|
{
|
||||||
|
for(size_t i=0; i<size; i++)
|
||||||
|
for(size_t o=0; o<ch; o++)
|
||||||
|
out[i*ch2 + o] = in[o*size + i];
|
||||||
|
|
||||||
|
if(ch != ch2)
|
||||||
|
for(size_t i=0; i<size; i++)
|
||||||
|
out[i*ch2 + 3] = alpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case UINT8:
|
||||||
|
convert(static_cast<const uint8_t*>(pixels), static_cast<uint8_t*>(image->data()), UINT8_MAX);
|
||||||
|
break;
|
||||||
|
case UINT16:
|
||||||
|
convert(static_cast<const uint16_t*>(pixels), static_cast<uint16_t*>(image->data()), UINT16_MAX);
|
||||||
|
break;
|
||||||
|
case UINT32:
|
||||||
|
convert(static_cast<const uint32_t*>(pixels), static_cast<uint32_t*>(image->data()), UINT32_MAX);
|
||||||
|
break;
|
||||||
|
case FLOAT32:
|
||||||
|
convert(static_cast<const float*>(pixels), static_cast<float*>(image->data()), 1);
|
||||||
|
break;
|
||||||
|
case FLOAT64:
|
||||||
|
convert(static_cast<const double*>(pixels), static_cast<double*>(image->data()), 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RawImage> RawImage::split() const
|
||||||
|
{
|
||||||
|
std::vector<RawImage> planes;
|
||||||
|
planes.resize(m_channels);
|
||||||
|
for(size_t i=0; i<m_channels; i++)
|
||||||
|
planes[i].allocate(m_width, m_height, 1, m_type);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return planes;
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-28
@@ -3,12 +3,11 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <opencv2/imgproc.hpp>
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QVector3D>
|
|
||||||
|
|
||||||
extern int THUMB_SIZE;
|
extern int THUMB_SIZE;
|
||||||
extern int THUMB_SIZE_BORDER;
|
extern int THUMB_SIZE_BORDER;
|
||||||
@@ -38,55 +37,71 @@ public:
|
|||||||
|
|
||||||
class RawImage
|
class RawImage
|
||||||
{
|
{
|
||||||
protected:
|
using PixelType = uint8_t;
|
||||||
cv::Mat m_img;
|
|
||||||
bool m_stats;
|
|
||||||
double m_mean;
|
|
||||||
double m_stdDev;
|
|
||||||
double m_median;
|
|
||||||
double m_min;
|
|
||||||
double m_max;
|
|
||||||
double m_mad;
|
|
||||||
float m_thumbAspect;
|
|
||||||
uint32_t m_saturated;
|
|
||||||
public:
|
public:
|
||||||
enum ImgType
|
enum DataType
|
||||||
{
|
{
|
||||||
UINT8,
|
UINT8,
|
||||||
UINT16,
|
UINT16,
|
||||||
|
UINT32,
|
||||||
FLOAT32,
|
FLOAT32,
|
||||||
UINT8C3,
|
FLOAT64,
|
||||||
UINT8C4,
|
|
||||||
UINT16C3,
|
|
||||||
UINT16C4,
|
|
||||||
FLOAT32C3,
|
|
||||||
UNKNOWN,
|
|
||||||
};
|
};
|
||||||
|
protected:
|
||||||
|
struct Stats
|
||||||
|
{
|
||||||
|
bool m_stats = false;
|
||||||
|
double m_mean[4] = {0.0};
|
||||||
|
double m_stdDev[4] = {0.0};
|
||||||
|
double m_median[4] = {0.0};
|
||||||
|
double m_min[4] = {0.0};
|
||||||
|
double m_max[4] = {0.0};
|
||||||
|
double m_mad[4] = {0.0};
|
||||||
|
};
|
||||||
|
std::unique_ptr<PixelType> m_pixels;
|
||||||
|
std::unique_ptr<PixelType> m_original;
|
||||||
|
uint32_t m_width = 0;
|
||||||
|
uint32_t m_height = 0;
|
||||||
|
uint32_t m_channels = 0;
|
||||||
|
uint32_t m_ch = 0;
|
||||||
|
DataType m_type = UINT8;
|
||||||
|
DataType m_origType = UINT8;
|
||||||
|
float m_thumbAspect = 0.0;
|
||||||
|
uint32_t m_saturated = 0.0;
|
||||||
|
Stats m_stats;
|
||||||
|
void allocate(uint32_t w, uint32_t h, uint32_t ch, DataType type);
|
||||||
|
public:
|
||||||
RawImage();
|
RawImage();
|
||||||
RawImage(int w, int h, ImgType type);
|
RawImage(uint32_t w, uint32_t h, uint32_t ch, DataType type);
|
||||||
RawImage(cv::Mat &img);
|
|
||||||
RawImage(const RawImage &d);
|
RawImage(const RawImage &d);
|
||||||
|
RawImage(RawImage &&d);
|
||||||
RawImage(const QImage &img);
|
RawImage(const QImage &img);
|
||||||
bool imageStats(double *mean, double *stdDev, double *median, double *min, double *max, double *mad, uint32_t *saturated);
|
bool imageStats(double *mean, double *stdDev, double *median, double *min, double *max, double *mad, uint32_t *saturated);
|
||||||
void calcStats();
|
void calcStats();
|
||||||
void rect(int &x, int &y, int w, int h, std::vector<double> &r) const;
|
void rect(int &x, int &y, int w, int h, std::vector<double> &r) const;
|
||||||
int findPeaks(double background, double distance, std::vector<Peak> &peaks) const;
|
int findPeaks(double background, double distance, std::vector<Peak> &peaks) const;
|
||||||
RawImage* medianFilter() const;
|
|
||||||
void quarter();
|
|
||||||
uint32_t width() const;
|
uint32_t width() const;
|
||||||
uint32_t height() const;
|
uint32_t height() const;
|
||||||
|
uint32_t channels() const;
|
||||||
uint32_t size() const;
|
uint32_t size() const;
|
||||||
ImgType type() const;
|
DataType type() const;
|
||||||
int dataType() const;
|
|
||||||
uint32_t norm() const;
|
uint32_t norm() const;
|
||||||
void* data();
|
void* data();
|
||||||
const void* data() const;
|
const void* data() const;
|
||||||
|
void* data(uint32_t row, uint32_t col = 0);
|
||||||
|
const void* data(uint32_t row, uint32_t col = 0) const;
|
||||||
|
void *origData(uint32_t row, uint32_t col = 0) const;
|
||||||
void convertToThumbnail();
|
void convertToThumbnail();
|
||||||
|
void convertToGLFormat();
|
||||||
float thumbAspect() const;
|
float thumbAspect() const;
|
||||||
const cv::Mat& mat() const;
|
bool pixel(int x, int y, double &r, double &g, double &b) const;
|
||||||
bool pixel(int x, int y, QVector3D &rgb) const;
|
|
||||||
void scaleToUnit();
|
void scaleToUnit();
|
||||||
void downscaleTo(uint32_t size);
|
void downscaleTo(uint32_t size);
|
||||||
|
|
||||||
|
static RawImage* fromPlanar(const RawImage &img);
|
||||||
|
static RawImage* fromPlanar(const void *pixels, uint32_t w, uint32_t h, uint32_t ch, DataType type);
|
||||||
|
static size_t typeSize(DataType type);
|
||||||
|
std::vector<RawImage> split() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RAWIMAGE_H
|
#endif // RAWIMAGE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user