From 4cc58de7a136493bc94187d8fcc0ce65d139b0f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Sat, 28 Sep 2019 11:51:04 +0200 Subject: [PATCH] Draw circles around peaks --- loadrunable.cpp | 28 +++++++++++++++++- rawimage.h | 76 +++++++++++++++++++++++++++++++------------------ 2 files changed, 76 insertions(+), 28 deletions(-) diff --git a/loadrunable.cpp b/loadrunable.cpp index 76f9ffa..acbfc96 100644 --- a/loadrunable.cpp +++ b/loadrunable.cpp @@ -3,6 +3,7 @@ #include #include "imageinfo.h" #include +#include #include #include #include "rawimage.h" @@ -25,6 +26,18 @@ void loadExifEntry(ImageInfoData &info, ExifContent *content, ExifTag tag) } } +void drawPeaks(QImage &img, const std::vector &peaks, bool half) +{ + QPixmap pix = QPixmap::fromImage(img); + QPainter painter(&pix); + painter.setPen(Qt::red); + for(auto peak : peaks) + { + painter.drawEllipse(QPoint(peak.x(), peak.y()), 5, 5); + } + img = pix.toImage(); +} + bool loadRAW(QString path, ImageInfoData &info, RawImageAbs **image, QImage *qimage) { if(!image && !qimage) @@ -231,7 +244,7 @@ void LoadRunable::run() } } - if(rawImage) + if(m_analyzeLevel >= Statistics) { uint64_t mean, median, min, max; double stdDev; @@ -241,7 +254,20 @@ void LoadRunable::run() info.append(StringPair(QObject::tr("Median"), QString::number(median))); info.append(StringPair(QObject::tr("Minimum"), QString::number(min))); info.append(StringPair(QObject::tr("Maximum"), QString::number(max))); + + if(m_analyzeLevel >= Peaks) + { + std::vector peaks; + rawImage->quarter(); + rawImage->medianFilter(); + int numPeaks = rawImage->findPeaks(median+stdDev, 20, peaks); + drawPeaks(img, peaks, true); + info.append(StringPair(QObject::tr("Peaks"), QString::number(numPeaks))); + info.append(StringPair(QObject::tr("Peaks draw"), QString::number(peaks.size()))); + } } + if(rawImage)delete rawImage; + QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(QImage, img), Q_ARG(ImageInfoData, info)); } diff --git a/rawimage.h b/rawimage.h index 25def99..0ff1f8e 100644 --- a/rawimage.h +++ b/rawimage.h @@ -7,10 +7,36 @@ #include #include +class Peak +{ + uint32_t m_v; + uint32_t m_x,m_y; +public: + Peak() : m_v(0), m_x(0), m_y(0) {} + Peak(uint32_t v, uint32_t x, uint32_t y) : m_v(v), m_x(x), m_y(y) {} + uint32_t v() const { return m_v; } + uint32_t x() const { return m_x; } + uint32_t y() const { return m_y; } + double distance(const Peak &d) const + { + uint32_t dx = m_x-d.m_x; + uint32_t dy = m_y-d.m_y; + return dx*dx + dy*dy; + } + bool operator <(const Peak &d) const + { + return m_v > d.m_v; + } +}; + class RawImageAbs { public: + virtual ~RawImageAbs(){} virtual bool imageStats(uint64_t *mean, double *stdDev, uint64_t *median, uint64_t *min, uint64_t *max) const = 0; + virtual int findPeaks(uint64_t background, double distance, std::vector &peaks) const = 0; + virtual void medianFilter() = 0; + virtual void quarter() = 0; }; template @@ -24,28 +50,6 @@ class RawImage : public RawImageAbs return c>=d; } public: - class Peak - { - T m_v; - uint32_t m_x,m_y; - public: - Peak() : m_v(0), m_x(0), m_y(0) {} - Peak(T v, uint32_t x, uint32_t y) : m_v(v), m_x(x), m_y(y) {} - T v() const { return m_v; } - uint32_t x() const { return m_x; } - uint32_t y() const { return m_y; } - double distance(const Peak &d) const - { - uint32_t dx = m_x-d.m_x; - uint32_t dy = m_y-d.m_y; - return dx*dx + dy*dy; - } - bool operator <(const Peak &d) const - { - return m_v > d.m_v; - } - }; - RawImage() { m_width = m_height = 0; @@ -122,7 +126,7 @@ public: if(y>=m_height)y=0; return m_img[y*m_width+x]; } - void findPeaks(T background, double distance, std::vector &peaks, T sigma) const + int findPeaks(uint64_t background, double distance, std::vector &peaks) const { std::vector tmpPeaks; const int r = 1; @@ -135,13 +139,14 @@ public: checkPixel(c, o+r, i-r) && checkPixel(c, o-r, i) && checkPixel(c, o+r, i) && checkPixel(c, o-r, i+r) && checkPixel(c, o, i+r) && checkPixel(c, o+r, i+r)) { - tmpPeaks.append(Peak(c, o, i)); + tmpPeaks.push_back(Peak(c, o, i)); } } } - std::qsort(tmpPeaks.begin(), tmpPeaks.end()); - tmpPeaks.resize(10000); + int num = tmpPeaks.size(); + std::sort(tmpPeaks.begin(), tmpPeaks.end()); + tmpPeaks.resize(std::min(num, 10000)); uint32_t d = distance*distance; for(const Peak &p : tmpPeaks) { @@ -156,9 +161,10 @@ public: } if(pass) { - peaks.append(p); + peaks.push_back(p); } } + return num; } void medianFilter() { @@ -178,6 +184,22 @@ public: } m_img = std::move(tmp); } + void quarter() + { + std::vector tmp; + tmp.resize(m_width*m_height); + uint32_t d = 0; + for(uint32_t i=0;i