ImageUtils.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "ImageUtils.h"
  2. #include <QtMath>
  3. #include <QDebug>
  4. GaussianBlur::GaussianBlur(int blurRadius, float sigma) : m_blurRadius(blurRadius), m_sigma(sigma)
  5. {
  6. CreateConvolutionMatrix();
  7. }
  8. QImage GaussianBlur::BlurImage(const QImage &in)
  9. {
  10. if (in.isNull())
  11. return QImage();
  12. QImage image(in.size(), in.format());
  13. qDebug() << m_convolutionMatrix;
  14. int matrixSize = m_convolutionMatrix.size();
  15. int halfMatrixSize = matrixSize / 2;
  16. float sumRed = 0.0f;
  17. float sumBlue = 0.0f;
  18. float sumGreen = 0.0f;
  19. float matrixValue = 0.0f;
  20. int x1 = 0, y1 = 0;
  21. for (int x = 0; x < in.width(); ++x) {
  22. for (int y = 0; y < in.height(); ++y) {
  23. for (int kx = -halfMatrixSize; kx <= halfMatrixSize; ++kx) {
  24. x1 = ReflectIndex(x - kx, in.width());
  25. QColor color(in.pixel(x1, y));
  26. matrixValue = m_convolutionMatrix[kx + halfMatrixSize];
  27. sumRed += color.red() * matrixValue;
  28. sumBlue += color.blue() * matrixValue;
  29. sumGreen += color.green() * matrixValue;
  30. }
  31. QRgb finalColor = qRgb(sumRed, sumGreen, sumBlue);
  32. image.setPixel(x, y, finalColor);
  33. sumRed = sumGreen = sumBlue = 0.0f;
  34. }
  35. }
  36. for (int x = 0; x < in.width(); ++x) {
  37. for (int y = 0; y < in.height(); ++y) {
  38. for (int ky = -halfMatrixSize; ky <= halfMatrixSize; ++ky) {
  39. y1 = ReflectIndex(y - ky, in.height());
  40. QColor color(image.pixel(x, y1));
  41. matrixValue = m_convolutionMatrix[ky + halfMatrixSize];
  42. sumRed += color.red() * matrixValue;
  43. sumBlue += color.blue() * matrixValue;
  44. sumGreen += color.green() * matrixValue;
  45. }
  46. QRgb finalColor = qRgb(sumRed, sumGreen, sumBlue);
  47. image.setPixel(x, y, finalColor);
  48. sumRed = sumGreen = sumBlue = 0.0f;
  49. }
  50. }
  51. return image;
  52. }
  53. float GaussianBlur::GaussFunc(float x)
  54. {
  55. // Gaussian function in one dimension
  56. return (1 / sqrtf(2 * M_PI * m_sigma * m_sigma)) * exp(-(x * x) / (2 * m_sigma * m_sigma));
  57. }
  58. void GaussianBlur::CreateConvolutionMatrix()
  59. {
  60. int x = 0;
  61. size_t matrixSize, halfMatrixSize;
  62. matrixSize = (size_t)(2 * m_blurRadius + 1);
  63. halfMatrixSize = matrixSize / 2;
  64. m_convolutionMatrix.resize(matrixSize);
  65. QVector<float>::iterator begin = m_convolutionMatrix.begin();
  66. QVector<float>::iterator end = m_convolutionMatrix.end();
  67. x = -(int)halfMatrixSize;
  68. std::for_each(begin, end, [&](float &val) mutable {
  69. val = GaussFunc(x);
  70. x++;
  71. });
  72. // normalize the values in the convolution matrix
  73. float sum = std::accumulate(begin, end, 0.0f);
  74. std::for_each(begin, end, [&](float &val) { val /= sum; });
  75. }
  76. int GaussianBlur::ReflectIndex(int x, int length)
  77. {
  78. if (x < 0)
  79. return -x - 1;
  80. else if (x >= length)
  81. return 2 * length - x - 1;
  82. return x;
  83. }
  84. float GaussianBlur::getSigma() const
  85. {
  86. return m_sigma;
  87. }
  88. void GaussianBlur::setSigma(float value)
  89. {
  90. m_sigma = value;
  91. CreateConvolutionMatrix();
  92. }
  93. int GaussianBlur::getBlurRadius() const
  94. {
  95. return m_blurRadius;
  96. }
  97. void GaussianBlur::setBlurRadius(int value)
  98. {
  99. m_blurRadius = value;
  100. CreateConvolutionMatrix();
  101. }
  102. GaussianBlur::~GaussianBlur() { }
  103. /// 最好用聚类均值法
  104. QColor DominantColor::getDominantColor(const QString &imagePath, int step)
  105. {
  106. // step步长:在图片中取点时两点之间的间隔,若为1,则取所有点,适当将此值调大有利于提高运行速度
  107. int t = 0; // 点数:记录一共取了多少个点,用于做计算平均数的分母
  108. QImage image(imagePath); // 将Pixmap类型转为QImage类型
  109. int r = 0, g = 0, b = 0; // 三元色的值,分别用于记录各个点的rgb值的和
  110. for (int i = 0; i < image.width(); i += step) {
  111. for (int j = 0; j < image.height(); j += step) {
  112. if (image.valid(i, j)) { // 判断该点是否有效
  113. t++; // 点数加一
  114. QColor c = image.pixel(i, j); // 获取该点的颜色
  115. r += c.red(); // 将获取到的各个颜色值分别累加到rgb三个变量中
  116. b += c.blue();
  117. g += c.green();
  118. }
  119. }
  120. }
  121. return QColor(int(r / t) > 255 ? 255 : int(r / t), int(g / t) > 255 ? 255 : int(g / t),
  122. int(b / t) > 255 ? 255 : int(b / t));
  123. }