7#include "fitshistogramview.h"
14#include "fitsviewer.h"
18#include <QtConcurrent>
51 m_HistogramIntensity.resize(3);
52 m_HistogramFrequency.resize(3);
53 for (
int i = 0; i < 3; i++)
55 m_HistogramIntensity[i].resize(256);
56 for (
int j = 0; j < 256; j++)
57 m_HistogramIntensity[i][j] = j;
58 m_HistogramFrequency[i].resize(256);
62void FITSHistogramView::showEvent(
QShowEvent * event)
65 if (m_ImageData.isNull())
67 if (!m_ImageData->isHistogramConstructed())
70 m_ImageData->constructHistogram();
72 createNonLinearHistogram();
77void FITSHistogramView::reset()
82void FITSHistogramView::syncGUI()
87 bool isColor = m_ImageData->channels() > 1;
92 for (
int n = 0; n < m_ImageData->channels(); n++)
98 graphs[n]->setData(m_HistogramIntensity[n], m_HistogramFrequency[n]);
103 graphs[n]->setData(m_ImageData->getHistogramIntensity(n), m_ImageData->getHistogramFrequency(n));
105 double median = m_ImageData->getMedian(n);
111 else if (median > .01)
113 else if (median > .0001)
120 graphs[RED_CHANNEL]->setBrush(QBrush(QColor(170, 40, 80)));
121 graphs[RED_CHANNEL]->setPen(QPen(
Qt::red));
125 graphs[GREEN_CHANNEL]->setBrush(QBrush(QColor(80, 40, 170)));
126 graphs[GREEN_CHANNEL]->setPen(QPen(
Qt::green));
128 graphs[BLUE_CHANNEL]->setBrush(QBrush(QColor(170, 40, 80)));
129 graphs[BLUE_CHANNEL]->setPen(QPen(
Qt::blue));
135 if (m_AxesLabelEnabled)
157void FITSHistogramView::resizePlot()
160 yAxis->setTickLabels(
false);
162 yAxis->setTickLabels(
true);
166void FITSHistogramView::driftMouseOverLine(
QMouseEvent * event)
168 double intensity =
xAxis->pixelToCoord(
event->localPos().x());
170 uint8_t channels = m_ImageData->channels();
171 QVector<double> freq(3, -1);
175 QVector<bool> inRange(3,
false);
176 for (
int n = 0; n < channels; n++)
178 if (intensity >= m_ImageData->getMin(n) && intensity <= m_ImageData->getMax(n))
182 if ( (channels == 1 && inRange[0] ==
false) || (!inRange[0] && !inRange[1] && !inRange[2]) )
189 if (
xAxis->range().contains(intensity))
191 for (
int n = 0; n < channels; n++)
193 int index = graphs[n]->findBegin(intensity,
true);
194 freq[n] = graphs[n]->dataMainValue(index);
197 if (channels == 1 && freq[0] > 0)
201 i18nc(
"Histogram tooltip; %1 is intensity; %2 is frequency;",
203 "<tr><td>Intensity: </td><td>%1</td></tr>"
204 "<tr><td>R Frequency: </td><td>%2</td></tr>"
209 else if (freq[1] > 0)
213 i18nc(
"Histogram tooltip; %1 is intensity; %2 is frequency;",
215 "<tr><td>Intensity: </td><td>%1</td></tr>"
216 "<tr><td>R Frequency: </td><td>%2</td></tr>"
217 "<tr><td>G Frequency: </td><td>%3</td></tr>"
218 "<tr><td>B Frequency: </td><td>%4</td></tr>"
236 connect(m_ImageData.data(), &FITSData::dataChanged, [
this]()
240 m_ImageData->resetHistogram();
241 m_ImageData->constructHistogram();
244 createNonLinearHistogram();
250void FITSHistogramView::createNonLinearHistogram()
254 int width = m_ImageData->width();
255 int height = m_ImageData->height();
257 const uint8_t channels = m_ImageData->channels();
265 for (
int i = 0; i < 256; i++)
266 rawImage.
setColor(i, qRgb(i, i, i));
273 Stretch stretch(
width,
height, m_ImageData->channels(), m_ImageData->dataType());
275 StretchParams stretchParams = stretch.computeParams(m_ImageData->getImageBuffer());
277 stretch.setParams(stretchParams);
278 stretch.run(m_ImageData->getImageBuffer(), &rawImage);
280 m_HistogramFrequency[0].fill(0);
283 m_HistogramFrequency[1].fill(0);
284 m_HistogramFrequency[2].fill(0);
287 const uint32_t sampleBy = (samples > 1000000 ? samples / 1000000 : 1);
290 for (
int h = 0; h <
height; h += sampleBy)
292 auto * scanLine = rawImage.
scanLine(h);
293 for (
int w = 0; w <
width; w += sampleBy)
294 m_HistogramFrequency[0][scanLine[w]] += sampleBy;
299 for (
int h = 0; h <
height; h += sampleBy)
301 auto * scanLine =
reinterpret_cast<const QRgb *
>((rawImage.
scanLine(h)));
302 for (
int w = 0; w <
width; w += sampleBy)
304 m_HistogramFrequency[0][qRed(scanLine[w])] += sampleBy;
305 m_HistogramFrequency[1][qGreen(scanLine[w])] += sampleBy;
306 m_HistogramFrequency[2][qBlue(scanLine[w])] += sampleBy;
315void FITSHistogramView::onXRangeChanged(
const QCPRange &range)
317 QCPRange boundedRange = range;
318 if(boundedRange.lower < 0) {
319 boundedRange.lower = 0;
320 boundedRange.upper = boundedRange.
size();
322 xAxis->setRange(boundedRange);
324void FITSHistogramView::onYRangeChanged(
const QCPRange &range)
326 QCPRange boundedRange = range;
327 if(boundedRange.lower < 0) {
328 boundedRange.lower = 0;
329 boundedRange.upper = boundedRange.
size();
331 yAxis->setRange(boundedRange);
void setRangeZoom(Qt::Orientations orientations)
void setRangeDrag(Qt::Orientations orientations)
Represents the range an axis is encompassing.
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
QCPGraph * addGraph(QCPAxis *keyAxis=nullptr, QCPAxis *valueAxis=nullptr)
void setInteraction(const QCP::Interaction &interaction, bool enabled=true)
void mouseMove(QMouseEvent *event)
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint)
QCPAxisRect * axisRect(int index=0) const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
@ iRangeDrag
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes)
@ iSelectPlottables
0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable)
@ iRangeZoom
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom,...
void setColor(int index, QRgb colorValue)
void setColorCount(int colorCount)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool event(QEvent *e)
QString number(double n, char format, int precision)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime)