#include "rawimage.h" #include #include int THUMB_SIZE = 128; int THUMB_SIZE_BORDER = 138; int THUMB_SIZE_BORDER_Y = 158; double SATURATION = 0.95; size_t RawImage::typeSize(RawImage::DataType type) { switch(type) { case RawImage::UINT8: return 1; case RawImage::UINT16: return 2; case RawImage::UINT32: case RawImage::FLOAT32: return 4; case RawImage::FLOAT64: return 8; default: return 1; } } void RawImage::allocate(uint32_t w, uint32_t h, uint32_t ch, DataType type) { m_width = w; m_height = h; m_channels = ch; m_ch = ch == 3 ? 4 : ch; m_origType = m_type = type; m_pixels = std::make_unique(m_width * m_height * m_ch * typeSize(type)); } RawImage::RawImage() { } RawImage::RawImage(uint32_t w, uint32_t h, uint32_t ch, DataType type) { allocate(w, h, ch, type); } RawImage::RawImage(const RawImage &d) { allocate(d.m_width, d.m_height, d.m_channels, d.m_type); std::memcpy(m_pixels.get(), d.m_pixels.get(), m_width * m_height * m_ch * typeSize(m_type)); m_stats = d.m_stats; 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) { qDebug() << img; if(img.format() == QImage::Format_RGBX8888) { allocate(img.width(), img.height(), 3, UINT8); for(int i=0; i(0, i); if(medianSum >= halfImageSize) { m_median = i; break; } } if(img.type() == CV_32F)m_median /= histSize; int threshold = SATURATION * histSize; m_saturated = 0; for(int i = histSize-1; i >= threshold; i--) m_saturated += hist.at(0, i); cv::Mat absDev; img.convertTo(absDev, CV_32F, 1, -m_median); absDev = cv::abs(absDev); cv::Mat madHist; medianSum = 0; cv::calcHist(&absDev, 1, nullptr, cv::Mat(), madHist, 1, &histSize, ranges); for(int i=0; i < histSize; i++) { medianSum += madHist.at(0, i); if(medianSum >= halfImageSize) { m_mad = i; break; } } if(img.type() == CV_32F)m_mad /= histSize;*/ } void RawImage::rect(int &x, int &y, int w, int h, std::vector &r) const { /*r.resize(w*h); x -= w/2; y -= h/2; if(x<0)x = 0; if(y<0)y = 0; if(x+w >= m_img.cols)x = m_img.cols-w; if(y+h >= m_img.rows)y = m_img.rows-h; cv::Mat roiImg(m_img, cv::Rect(x, y, w, h)); cv::Mat doubleMat; roiImg.convertTo(doubleMat, CV_64F); r = std::vector(doubleMat.begin(), doubleMat.end());*/ } int RawImage::findPeaks(double background, double distance, std::vector &peaks) const { /*std::vector> contours; cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(distance, distance)); cv::Mat img, mask, dilate, locMax, result; if(m_img.channels() == 1)img = m_img; else cv::cvtColor(m_img, img, cv::COLOR_RGB2GRAY); cv::dilate(img, dilate, kernel); cv::compare(img, dilate, locMax, cv::CMP_GE); cv::compare(img, cv::Scalar(background), mask, cv::CMP_GT); cv::bitwise_and(locMax, mask, result); cv::findContours(result, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); peaks.reserve(contours.size()); for(auto contour : contours) { peaks.push_back(Peak(1, contour[0].x, contour[0].y)); } return peaks.size();*/ } uint32_t RawImage::width() const { return m_width; } uint32_t RawImage::height() const { return m_height; } uint32_t RawImage::channels() const { return m_channels; } uint32_t RawImage::size() const { return width()*height(); } RawImage::DataType RawImage::type() const { return m_type; } uint32_t RawImage::norm() const { switch(m_type) { case UINT8: return UINT8_MAX; case UINT16: return UINT16_MAX; case UINT32: return UINT32_MAX; default: return 1; } } void* RawImage::data() { return m_pixels.get(); } const void *RawImage::data() const { 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() { m_thumbAspect = (float)width() / height(); std::unique_ptr outptr = std::make_unique(THUMB_SIZE * THUMB_SIZE * 4 * sizeof(uint16_t)); uint16_t *out = reinterpret_cast(outptr.get()); auto loop = [&](uint16_t *out, auto *in, auto scale) { for(int i=0; i(m_pixels.get()), 256); break; case UINT16: loop(out, reinterpret_cast(m_pixels.get()), 1); break; case UINT32: loop(out, reinterpret_cast(m_pixels.get()), UINT16_MAX/(float)UINT32_MAX); break; case FLOAT32: loop(out, reinterpret_cast(m_pixels.get()), 65535.0); break; default: qWarning() << "FLOAT64 should not happend"; return; } m_pixels = std::move(outptr); m_width = THUMB_SIZE; m_height = THUMB_SIZE; m_ch = 4; m_channels = 3; 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(m_pixels.get()); uint32_t *src = reinterpret_cast(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(m_pixels.get()); double *src = reinterpret_cast(m_original.get()); for(size_t i = 0; i < s; i++) dst[i] = src[i]; } } float RawImage::thumbAspect() const { return m_thumbAspect; } bool RawImage::pixel(int x, int y, double &r, double &g, double &b) const { if(x < 0 || y < 0 || x >= (int)width() || y >= (int)height())return false; switch(m_origType) { case UINT8: { const uint8_t *v = static_cast(origData(y, x)); if(m_channels == 1) { r = g = b = *v; } else { r = v[0]; g = v[1]; b = v[2]; } break; } case UINT16: { const uint16_t *v = static_cast(origData(y, x)); if(m_channels == 1) { r = g = b = *v; } else { r = v[0]; g = v[1]; b = v[2]; } break; } case UINT32: { const uint32_t *v = static_cast(origData(y, x)); if(m_channels == 1) { r = g = b = *v; } else { r = v[0]; g = v[1]; b = v[2]; } break; } case FLOAT32: { const float *v = static_cast(origData(y, x)); if(m_channels == 1) { r = g = b = *v; } else { r = v[0]; g = v[1]; b = v[2]; } break; } case FLOAT64: { const double *v = static_cast(origData(y, x)); if(m_channels == 1) { r = g = b = *v; } else { r = v[0]; g = v[1]; b = v[2]; } break; } } return true; } void RawImage::scaleToUnit() { /*if(CV_MAT_DEPTH(m_img.type()) == CV_32F) { double min, max; cv::minMaxIdx(m_img, &min, &max); if(min < 0 || max > 1) { float scale = 1.0 / (max - min); float zero = min * scale; m_img = m_img * scale - zero; } }*/ } void RawImage::downscaleTo(uint32_t size) { /*if(size < width() || size < height()) { double s = (double)size / std::max(width(), height()); cv::Size dsize(std::floor(width() * s), std::floor(height() * s)); 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(pixels), static_cast(image->data()), UINT8_MAX); break; case UINT16: convert(static_cast(pixels), static_cast(image->data()), UINT16_MAX); break; case UINT32: convert(static_cast(pixels), static_cast(image->data()), UINT32_MAX); break; case FLOAT32: convert(static_cast(pixels), static_cast(image->data()), 1); break; case FLOAT64: convert(static_cast(pixels), static_cast(image->data()), 1); break; } return image; } std::vector RawImage::split() const { std::vector planes; planes.resize(m_channels); for(size_t i=0; i