C++ 将图像转换为灰度
我有一个QImage,我需要把它转换成灰度,然后在上面画上颜色。我找到了一个C++ 将图像转换为灰度,c++,qt,grayscale,qimage,C++,Qt,Grayscale,Qimage,我有一个QImage,我需要把它转换成灰度,然后在上面画上颜色。我找到了一个allGray()和isGrayScale()函数来检查图像是否已经是灰度的,但是没有toGrayScale()或类似的命名函数 QImage convertToGrayScale(const QImage &srcImage) { // Convert to 32bit pixel format QImage dstImage = srcImage.convertToFormat(srcIm
allGray()
和isGrayScale()
函数来检查图像是否已经是灰度的,但是没有toGrayScale()
或类似的命名函数
QImage convertToGrayScale(const QImage &srcImage) {
// Convert to 32bit pixel format
QImage dstImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ?
QImage::Format_ARGB32 : QImage::Format_RGB32);
unsigned int *data = (unsigned int*)dstImage.bits();
int pixelCount = dstImage.width() * dstImage.height();
// Convert each pixel to grayscale
for(int i = 0; i < pixelCount; ++i) {
int val = qGray(*data);
*data = qRgba(val, val, val, qAlpha(*data));
++data;
}
return dstImage;
}
现在我正在使用这段代码,但它的性能不是很好:
for (int ii = 0; ii < image.width(); ii++) {
for (int jj = 0; jj < image.height(); jj++) {
int gray = qGray(image.pixel(ii, jj));
image.setPixel(ii, jj, QColor(gray, gray, gray).rgb());
}
}
for(int ii=0;ii
在性能方面,将QImage转换为灰度的最佳方法是什么?使用
QImage::scanline
访问数据。扫描(水平线)上的像素是连续的。假设您有一个32 bpp的映像,您可以使用QRgb在扫描过程中进行迭代。最后,始终将x坐标放在内部循环中。其中:
for (int ii = 0; ii < image.height(); ii++) {
uchar* scan = image.scanLine(ii);
int depth =4;
for (int jj = 0; jj < image.width(); jj++) {
QRgb* rgbpixel = reinterpret_cast<QRgb*>(scan + jj*depth);
int gray = qGray(*rgbpixel);
*rgbpixel = QColor(gray, gray, gray).rgba();
}
}
源代码:
testimage.h文件:
#ifndef TESTIMAGE_H
#define TESTIMAGE_H
#include <QtTest/QtTest>
#include <QObject>
#include <QImage>
class TestImage : public QObject
{
Q_OBJECT
public:
explicit TestImage(QObject *parent = 0);
signals:
private slots:
void grayscaleOp();
void grayscaleFast();
private:
QImage imgop;
QImage imgfast;
};
#endif // TESTIMAGE_H
重要提示:
- 通过反转循环,您已经获得了重要的性能提升。在这个测试用例中,它是
~90ms
- 您可以使用其他库(如opencv)进行灰度转换,然后从opencv缓冲区构建Qimage。我期待着更好的性能改进李>
// We assume the format to be RGB32!!!
Q_ASSERT(image.format() == QImage::Format_RGB32);
for (int ii = 0; ii < image.height(); ii++) {
QRgb *pixel = reinterpret_cast<QRgb*>(image.scanLine(ii));
QRgb *end = pixel + image.width();
for (; pixel != end; pixel++) {
int gray = qGray(*pixel);
*pixel = QColor(gray, gray, gray).rgb();
}
}
//我们假设格式为RGB32!!!
Q_断言(image.format()==QImage::format_RGB32);
对于(int ii=0;ii
内部qt类QPixmapColorizeFilter
使用函数grayscale
解决类似问题
我从中导出了以下函数,应该可以解决这个问题
重要的部分是将图像转换成32位格式,这样你就可以把每个像素看作32位的值,而不需要关心位对齐。 您还可以直接使用
bits
函数,在所有像素上迭代,而不是在行和列上迭代。使用此技巧可以避免在scanLine
函数中执行乘法
QImage convertToGrayScale(const QImage &srcImage) {
// Convert to 32bit pixel format
QImage dstImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ?
QImage::Format_ARGB32 : QImage::Format_RGB32);
unsigned int *data = (unsigned int*)dstImage.bits();
int pixelCount = dstImage.width() * dstImage.height();
// Convert each pixel to grayscale
for(int i = 0; i < pixelCount; ++i) {
int val = qGray(*data);
*data = qRgba(val, val, val, qAlpha(*data));
++data;
}
return dstImage;
}
QImage convertToGrayScale(常量QImage&srcImage){
//转换为32位像素格式
QImage dstImage=srcImage.convertToFormat(srcImage.hasAlphaChannel()?
QImage::Format_ARGB32:QImage::Format_RGB32);
unsigned int*数据=(unsigned int*)dstmimage.bits();
int pixelCount=dstImage.width()*dstImage.height();
//将每个像素转换为灰度
对于(int i=0;i
自Qt 5.5以来,您可以调用将QImage转换为灰度,如下所示:
QImage image = ...;
image.convertToFormat(QImage::Format_Grayscale8);
虽然这仍然不是最好的方法,但是尝试切换for循环(因此首先迭代ii,然后迭代jj)。根据内存布局的不同,这可能会导致更好的缓存一致性,并使代码更快。@Daerst是的,这是一个很好的建议,但如果我找到了更好的解决方案,优化解决方案就没有意义了。如果没有其他解决方案,那么当保证两行之间有连续像素时,.bits可能会起作用。我用扫描线来比较保守。例如,使用
QImage::QImage(uchar*data,int-width,int-height,int-bytesPerLine,Format-Format)
创建的图像可能具有bytesPerLine>width*sizeofpixel()
。这应该是公认的答案。为我工作-谢谢:)
QImage convertToGrayScale(const QImage &srcImage) {
// Convert to 32bit pixel format
QImage dstImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ?
QImage::Format_ARGB32 : QImage::Format_RGB32);
unsigned int *data = (unsigned int*)dstImage.bits();
int pixelCount = dstImage.width() * dstImage.height();
// Convert each pixel to grayscale
for(int i = 0; i < pixelCount; ++i) {
int val = qGray(*data);
*data = qRgba(val, val, val, qAlpha(*data));
++data;
}
return dstImage;
}
QImage image = ...;
image.convertToFormat(QImage::Format_Grayscale8);