基于直方图算法实现通过qt实现匀光匀色的两种方法 您所在的位置:网站首页 图像MASK和wallis匀光算法 基于直方图算法实现通过qt实现匀光匀色的两种方法

基于直方图算法实现通过qt实现匀光匀色的两种方法

2024-06-14 14:32| 来源: 网络整理| 查看: 265

第一步,在QT中配置opencv

Qt配置OpenCV(保姆级教程)_qt opencv安装-CSDN博客

参考这个写的非常详细。

方法一

基于opencv库的实现

OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理函数和工具,能够方便地实现各种图像处理操作,包括直方图均衡化、像素操作等。

采用了直方图匹配算法:直方图匹配是一种常见的图像增强方法,通过调整像素的灰度分布,使得输出图像的直方图更接近于目标直方图,从而达到图像增强的目的。

代码

#include #include #include using namespace std; using namespace cv; void getSigBandImgHistogram(Mat SrcImage, map &SrcImg_SigMap, int BandId); int main(int argc, char* argv[]) { const char* SrcPath = "D:/image2/daichuli.png"; const char* BaseMap = "D:/image2/1.png"; const char* outPutPath = "D:/image2/outPut.png"; int IsDislay = atoi(argv[4]);//是否显示匹配后影像效果,0为不显示,其他的都显示 Mat SrcImage = imread(SrcPath); Mat BaseMapImg = imread(BaseMap); cout addWidget(m_labelReference); QPushButton *buttonSelectReference = new QPushButton("选择参考图片", this); connect(buttonSelectReference, &QPushButton::clicked, this, &Widget::on_selectReferenceImage); mainLayout->addWidget(buttonSelectReference); m_labelTarget = new QLabel(this); mainLayout->addWidget(m_labelTarget); QPushButton *buttonSelectTarget = new QPushButton("选择待处理图片", this); connect(buttonSelectTarget, &QPushButton::clicked, this, &Widget::on_selectTargetImage); mainLayout->addWidget(buttonSelectTarget); QPushButton *buttonProcess = new QPushButton("处理图片", this); connect(buttonProcess, &QPushButton::clicked, this, &Widget::on_processImage); mainLayout->addWidget(buttonProcess); setLayout(mainLayout); } void Widget::on_selectReferenceImage() { QString referenceImagePath = QFileDialog::getOpenFileName(this, tr("选择参考图片"), "", tr("Images (*.png *.jpg)")); if (!referenceImagePath.isEmpty()) { m_referenceImage = QImage(referenceImagePath);//选路径图片 m_labelReference->setPixmap(QPixmap::fromImage(m_referenceImage).scaled(400, 400, Qt::KeepAspectRatio)); } } void Widget::on_selectTargetImage() { QString targetImagePath = QFileDialog::getOpenFileName(this, tr("选择待处理图片"), "", tr("Images (*.png *.jpg)")); if (!targetImagePath.isEmpty()) { m_targetImage = QImage(targetImagePath); m_labelTarget->setPixmap(QPixmap::fromImage(m_targetImage).scaled(400, 400, Qt::KeepAspectRatio)); } } void Widget::on_processImage() { if (m_referenceImage.isNull() || m_targetImage.isNull()) { return; } // 在这里使用选定的参考图像m_referenceImage对待处理的图像m_targetImage进行匀光匀色处理 // 进行直方图匹配处理 m_processedImage = histogramMatching(m_referenceImage, m_targetImage); // 将处理后的图像保存在m_processedImage中 // m_processedImage = processImageWithReference(m_referenceImage, m_targetImage); // 显示处理后的图像 QLabel *processedLabel = new QLabel(this); processedLabel->setPixmap(QPixmap::fromImage(m_processedImage).scaled(400, 400, Qt::KeepAspectRatio)); QVBoxLayout *mainlayout = qobject_cast(layout()); mainlayout->addWidget(processedLabel); // 将处理后的图片保存为 PNG 格式文件到桌面 QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); QString filePath = desktopPath + "/processed_image.png"; m_processedImage.save(filePath, "PNG"); } QImage Widget::processImageWithReference(const QImage& referenceImg, const QImage& targetImg) { // 在这里实现匀光匀色处理算法,并返回处理后的图像 QImage processedImg = histogramMatching(referenceImg, targetImg); // 这里暂时将目标图像作为处理后的图像,需要替换成实际的处理算法 return processedImg; } QImage Widget::histogramMatching(const QImage& referenceImg, const QImage& targetImg)//建立了一个查找表,其实就是根据差值表和累积直方图的关系生成的。 { // 计算模板影像和待处理影像的累积直方图 QVector referenceHistograms = calculateCumulativeHistogram(referenceImg); QVector targetHistograms = calculateCumulativeHistogram(targetImg); // 生成查找表 QVector lookupTables; for (int channel = 0; channel < 3; ++channel) { QVector lookupTable; for (int i = 0; i < 256; ++i) { int nearestIndex = findNearestValueIndex(referenceHistograms, targetHistograms[channel][i]); lookupTable.append(nearestIndex); } lookupTables.append(lookupTable); } // 应用查找表对待处理图像进行处理 QImage processedImg = applyLookupTable(targetImg, lookupTables); return processedImg; } QVectorWidget:: calculateCumulativeHistogram(const QImage& image) { QVector cumulativeHistograms(3, QVector(256, 0.0)); int width = image.width(); int height = image.height(); double totalPixel = width * height; double rate = 1.0 / (3.0 * totalPixel); for (int channel = 0; channel < 3; ++channel) { QVector histogram(256, 0.0); // 统计每个通道的直方图 for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { QRgb pixelValue = image.pixel(x, y); int colorValue=0; if (channel == 0) { colorValue = qGreen(pixelValue) ; colorValue = qBound(0, colorValue, 255); } else if (channel == 1) { colorValue = qRed(pixelValue); // 对绿色通道进行加权处理 colorValue = qBound(0, colorValue, 255); if (colorValue > 255) colorValue = 255; // 确保不超过255 } else if (channel == 2) { colorValue = qBlue(pixelValue); colorValue = qBound(0, colorValue, 255); } Q_ASSERT_X(colorValue >= 0 && colorValue < histogram.size(), "QList::operator[]", "index out of range"); // histogram[colorValue] += 1.0; ++histogram[colorValue]; } } // 计算累积直方图 cumulativeHistograms[channel][0] = histogram[0]; for (int i = 1; i < 256; ++i) { cumulativeHistograms[channel][i] = cumulativeHistograms[channel][i - 1] + histogram[i]; } // 归一化到0~1之间 for (int i = 0; i < 256; ++i) { // cumulativeHistograms[channel][i] /= totalPixel; cumulativeHistograms[channel][i] = std::round(cumulativeHistograms[channel][i] / totalPixel * 255.0); } } return cumulativeHistograms; } //int Widget::findNearestValueIndex(const QList& referenceHistograms, double value) int Widget::findNearestValueIndex(const QVector& referenceHistograms, double value)//找到差值表中的最小值索引 { int index = 0; double minDiff = qAbs(referenceHistograms[0][0] - value); // 找到最接近值的索引 for (int i = 0; i < referenceHistograms.size(); ++i) { for (int j = 0; j < referenceHistograms[i].size(); ++j) { double diff = qAbs(referenceHistograms[i][j] - value); if (diff < minDiff) { minDiff = diff; index = j; } } } return index; } QImage Widget::applyLookupTable(const QImage& image, const QVector& lookupTables) { QImage processedImage = image; // 应用查找表到红绿蓝三个通道 for (int y = 0; y < processedImage.height(); ++y) { for (int x = 0; x < processedImage.width(); ++x) { QRgb pixelValue = processedImage.pixel(x, y); int r = qRed(pixelValue); int g = qGreen(pixelValue); int b = qBlue(pixelValue); int newR = lookupTables[0][r]; int newG = lookupTables[1][g]; int newB = lookupTables[2][b]; processedImage.setPixel(x, y, qRgb(newR, newG, newB)); } } return processedImage; } Widget::~Widget() { QLayout *layout = this->layout(); if (layout) { QLayoutItem *item; while ((item = layout->takeAt(0))) { delete item->widget(); delete item; } delete layout; } delete m_labelReference; delete m_labelTarget; }

运行后明显基于opencv的更清晰,不过可以根据你想要实现的颜色在代码中做调整



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有