177 lines
6.9 KiB
C++
177 lines
6.9 KiB
C++
#include <QApplication>
|
|
#include <QCommandLineParser>
|
|
#include <QDebug>
|
|
#include <csignal>
|
|
#include <QJsonObject>
|
|
#include <QTextStream>
|
|
#include "hyperiongrabber.h"
|
|
#include "HyperionProcessor.h"
|
|
#include "LedColorMapping.h"
|
|
|
|
// ANSI escape code to clear the screen
|
|
const QString ANSI_RESET = "\033[0m";
|
|
|
|
// Function to get a printable block with a specific background color
|
|
QString getAnsiColorBlock(const QColor& color) {
|
|
if (!color.isValid()) {
|
|
return " ";
|
|
}
|
|
// Use 24-bit color ANSI escape codes
|
|
return QString("\033[48;2;%1;%2;%3m ").arg(color.red()).arg(color.green()).arg(color.blue());
|
|
}
|
|
|
|
void printLedColorsAsBoxes(const QVector<QColor>& ledColors) {
|
|
QTextStream cout(stdout);
|
|
for (const QColor& color : ledColors) {
|
|
cout << getAnsiColorBlock(color);
|
|
}
|
|
cout << ANSI_RESET << "\n";
|
|
cout.flush();
|
|
}
|
|
|
|
|
|
static HyperionGrabber *grabber = nullptr;
|
|
static QApplication *app = nullptr;
|
|
static HyperionProcessor *processor = nullptr;
|
|
|
|
void quit(int) {
|
|
if (grabber != nullptr) {
|
|
delete grabber;
|
|
}
|
|
if (processor != nullptr) {
|
|
delete processor;
|
|
}
|
|
if (app != nullptr) {
|
|
app->quit();
|
|
}
|
|
}
|
|
|
|
class GrabberConfigurator : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
GrabberConfigurator(const QHash<QString, QString> &opts, const LedLayout& layout, const QJsonObject& config, QObject *parent = nullptr)
|
|
: QObject(parent), _layout(layout)
|
|
{
|
|
grabber = new HyperionGrabber(opts);
|
|
processor = new HyperionProcessor(layout, config);
|
|
connect(grabber, &HyperionGrabber::imageReady, this, &GrabberConfigurator::processFrame);
|
|
}
|
|
|
|
public slots:
|
|
void processFrame(const QImage &image) {
|
|
qDebug() << "GrabberConfigurator::processFrame called.";
|
|
if (image.isNull()) return;
|
|
|
|
// Process the image with HyperionProcessor
|
|
QVector<QColor> ledColors = processor->process(image);
|
|
|
|
// Debugging: Print some sample LED colors
|
|
if (!ledColors.isEmpty()) {
|
|
qDebug() << "Sample LED Colors:";
|
|
qDebug() << " LED 0:" << ledColors.at(0).name();
|
|
if (ledColors.size() > 1) qDebug() << " LED 1:" << ledColors.at(1).name();
|
|
if (ledColors.size() > _layout.bottom) qDebug() << " LED (bottom+1):" << ledColors.at(_layout.bottom).name();
|
|
if (ledColors.size() > _layout.bottom + _layout.right) qDebug() << " LED (bottom+right+1):" << ledColors.at(_layout.bottom + _layout.right).name();
|
|
}
|
|
|
|
// Get the processed image dimensions and border info
|
|
QSize processedImageSize = processor->getLastImageSize();
|
|
BlackBorder border = processor->getLastBorder();
|
|
|
|
// Calculate the content rectangle
|
|
int xOffset = border.verticalSize;
|
|
int yOffset = border.horizontalSize;
|
|
int contentWidth = processedImageSize.width() - (2 * border.verticalSize);
|
|
int contentHeight = processedImageSize.height() - (2 * border.horizontalSize);
|
|
|
|
if (contentWidth > 0 && contentHeight > 0) {
|
|
// QImage croppedImage = image.copy(xOffset, yOffset, contentWidth, contentHeight);
|
|
|
|
// Debugging: Print ledMap details
|
|
const QVector<QVector<QPoint>>& ledMap = processor->getLedMap();
|
|
qDebug() << "ledMap size:" << ledMap.size();
|
|
|
|
for (int i = 0; i < ledColors.size(); ++i) {
|
|
const QColor& color = ledColors.at(i);
|
|
const QVector<QPoint>& pixels = ledMap.at(i);
|
|
qDebug() << " LED" << i << "pixels size:" << pixels.size();
|
|
|
|
// Debugging: Print rectangle dimensions (if needed, can be re-enabled)
|
|
// int minX = image.width(); int minY = image.height(); int maxX = 0; int maxY = 0;
|
|
// for (const QPoint& p : pixels) { minX = qMin(minX, p.x()); minY = qMin(minY, p.y()); maxX = qMax(maxX, p.x()); maxY = qMax(maxY, p.y()); }
|
|
// int rectMinX = minX - xOffset; int rectMinY = minY - yOffset;
|
|
// int rectWidth = qMax(1, maxX - minX + 1); int rectHeight = qMax(1, maxY - minY + 1);
|
|
// qDebug() << "LED" << i << ": Rect(" << rectMinX << "," << rectMinY << "," << rectWidth << "," << rectHeight << ") Color:" << color.name();
|
|
}
|
|
|
|
// Print LED colors as a line of boxes in the terminal
|
|
printLedColorsAsBoxes(ledColors);
|
|
|
|
} else {
|
|
qDebug() << "No content to process after black border removal.";
|
|
}
|
|
}
|
|
|
|
private:
|
|
LedLayout _layout; // Still needed for HyperionProcessor constructor
|
|
};
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
app = new QApplication(argc, argv);
|
|
signal(SIGINT, quit);
|
|
signal(SIGTERM, quit);
|
|
|
|
QApplication::setApplicationName("GrabberConfigurator");
|
|
QApplication::setApplicationVersion("0.2");
|
|
|
|
QCommandLineParser parser;
|
|
parser.setApplicationDescription("A tool to test the Hyperion processing pipeline.");
|
|
parser.addHelpOption();
|
|
parser.addVersionOption();
|
|
|
|
// Add options for HyperionGrabber (scale, frameskip, etc.)
|
|
parser.addOption(QCommandLineOption(QStringList() << "s" << "scale", "Divisor used to scale your screen resolution (e.g., 8).", "scale", "8"));
|
|
parser.addOption(QCommandLineOption(QStringList() << "f" << "frameskip", "Number of frames to skip between captures (e.g., 1).", "frameskip", "0"));
|
|
|
|
// Add options for the LED layout
|
|
parser.addOption(QCommandLineOption(QStringList() << "leds-bottom", "Number of LEDs on the bottom edge.", "count", "70"));
|
|
parser.addOption(QCommandLineOption(QStringList() << "leds-right", "Number of LEDs on the right edge.", "count", "20"));
|
|
parser.addOption(QCommandLineOption(QStringList() << "leds-top", "Number of LEDs on the top edge.", "count", "70"));
|
|
parser.addOption(QCommandLineOption(QStringList() << "leds-left", "Number of LEDs on the left edge.", "count", "20"));
|
|
|
|
// Add options for the processor
|
|
parser.addOption(QCommandLineOption(QStringList() << "bbt", "Black border threshold (0.0 to 1.0).", "threshold", "0.1"));
|
|
|
|
parser.process(*app);
|
|
|
|
QHash<QString, QString> grabberOpts;
|
|
grabberOpts.insert("scale", parser.value("scale"));
|
|
grabberOpts.insert("frameskip", parser.value("frameskip"));
|
|
|
|
LedLayout layout;
|
|
layout.bottom = parser.value("leds-bottom").toInt();
|
|
layout.right = parser.value("leds-right").toInt();
|
|
layout.top = parser.value("leds-top").toInt();
|
|
layout.left = parser.value("leds-left").toInt();
|
|
|
|
QJsonObject processorConfig;
|
|
processorConfig["blackBorderThreshold"] = parser.value("bbt").toDouble();
|
|
|
|
// No QLabel or QWidget needed for this visualization
|
|
// QWidget window;
|
|
// QLabel label;
|
|
// label.setParent(&window);
|
|
// label.setScaledContents(true);
|
|
// window.show();
|
|
|
|
GrabberConfigurator configurator(grabberOpts, layout, processorConfig);
|
|
|
|
qInfo() << "Starting GrabberConfigurator. A line of colored boxes should appear in the terminal. Press Ctrl+C to exit.";
|
|
|
|
return app->exec();
|
|
}
|
|
|
|
#include "grabberconfigurator.moc" |