123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #include "ImageUtils.h"
- #include <QtMath>
- #include <QDebug>
- GaussianBlur::GaussianBlur(int blurRadius, float sigma) : m_blurRadius(blurRadius), m_sigma(sigma)
- {
- CreateConvolutionMatrix();
- }
- QImage GaussianBlur::BlurImage(const QImage &in)
- {
- if (in.isNull())
- return QImage();
- QImage image(in.size(), in.format());
- qDebug() << m_convolutionMatrix;
- int matrixSize = m_convolutionMatrix.size();
- int halfMatrixSize = matrixSize / 2;
- float sumRed = 0.0f;
- float sumBlue = 0.0f;
- float sumGreen = 0.0f;
- float matrixValue = 0.0f;
- int x1 = 0, y1 = 0;
- for (int x = 0; x < in.width(); ++x) {
- for (int y = 0; y < in.height(); ++y) {
- for (int kx = -halfMatrixSize; kx <= halfMatrixSize; ++kx) {
- x1 = ReflectIndex(x - kx, in.width());
- QColor color(in.pixel(x1, y));
- matrixValue = m_convolutionMatrix[kx + halfMatrixSize];
- sumRed += color.red() * matrixValue;
- sumBlue += color.blue() * matrixValue;
- sumGreen += color.green() * matrixValue;
- }
- QRgb finalColor = qRgb(sumRed, sumGreen, sumBlue);
- image.setPixel(x, y, finalColor);
- sumRed = sumGreen = sumBlue = 0.0f;
- }
- }
- for (int x = 0; x < in.width(); ++x) {
- for (int y = 0; y < in.height(); ++y) {
- for (int ky = -halfMatrixSize; ky <= halfMatrixSize; ++ky) {
- y1 = ReflectIndex(y - ky, in.height());
- QColor color(image.pixel(x, y1));
- matrixValue = m_convolutionMatrix[ky + halfMatrixSize];
- sumRed += color.red() * matrixValue;
- sumBlue += color.blue() * matrixValue;
- sumGreen += color.green() * matrixValue;
- }
- QRgb finalColor = qRgb(sumRed, sumGreen, sumBlue);
- image.setPixel(x, y, finalColor);
- sumRed = sumGreen = sumBlue = 0.0f;
- }
- }
- return image;
- }
- float GaussianBlur::GaussFunc(float x)
- {
- // Gaussian function in one dimension
- return (1 / sqrtf(2 * M_PI * m_sigma * m_sigma)) * exp(-(x * x) / (2 * m_sigma * m_sigma));
- }
- void GaussianBlur::CreateConvolutionMatrix()
- {
- int x = 0;
- size_t matrixSize, halfMatrixSize;
- matrixSize = (size_t)(2 * m_blurRadius + 1);
- halfMatrixSize = matrixSize / 2;
- m_convolutionMatrix.resize(matrixSize);
- QVector<float>::iterator begin = m_convolutionMatrix.begin();
- QVector<float>::iterator end = m_convolutionMatrix.end();
- x = -(int)halfMatrixSize;
- std::for_each(begin, end, [&](float &val) mutable {
- val = GaussFunc(x);
- x++;
- });
- // normalize the values in the convolution matrix
- float sum = std::accumulate(begin, end, 0.0f);
- std::for_each(begin, end, [&](float &val) { val /= sum; });
- }
- int GaussianBlur::ReflectIndex(int x, int length)
- {
- if (x < 0)
- return -x - 1;
- else if (x >= length)
- return 2 * length - x - 1;
- return x;
- }
- float GaussianBlur::getSigma() const
- {
- return m_sigma;
- }
- void GaussianBlur::setSigma(float value)
- {
- m_sigma = value;
- CreateConvolutionMatrix();
- }
- int GaussianBlur::getBlurRadius() const
- {
- return m_blurRadius;
- }
- void GaussianBlur::setBlurRadius(int value)
- {
- m_blurRadius = value;
- CreateConvolutionMatrix();
- }
- GaussianBlur::~GaussianBlur() { }
- /// 最好用聚类均值法
- QColor DominantColor::getDominantColor(const QString &imagePath, int step)
- {
- // step步长:在图片中取点时两点之间的间隔,若为1,则取所有点,适当将此值调大有利于提高运行速度
- int t = 0; // 点数:记录一共取了多少个点,用于做计算平均数的分母
- QImage image(imagePath); // 将Pixmap类型转为QImage类型
- int r = 0, g = 0, b = 0; // 三元色的值,分别用于记录各个点的rgb值的和
- for (int i = 0; i < image.width(); i += step) {
- for (int j = 0; j < image.height(); j += step) {
- if (image.valid(i, j)) { // 判断该点是否有效
- t++; // 点数加一
- QColor c = image.pixel(i, j); // 获取该点的颜色
- r += c.red(); // 将获取到的各个颜色值分别累加到rgb三个变量中
- b += c.blue();
- g += c.green();
- }
- }
- }
- return QColor(int(r / t) > 255 ? 255 : int(r / t), int(g / t) > 255 ? 255 : int(g / t),
- int(b / t) > 255 ? 255 : int(b / t));
- }
|