将QImage转换为灰度 [英] Convert a QImage to grayscale
问题描述
我有一个QImage,我需要将其转换为灰度,然后再涂上颜色。我发现一个 allGray()
和 isGrayScale()
函数检查图像是否已经是灰度, c $ c> toGrayScale()或类似命名的函数。
I have a QImage and I need to convert it to grayscale, then later paint over that with colors. I found an allGray()
and isGrayScale()
function to check if an image is already grayscale, but no toGrayScale()
or similarly-named function.
现在我使用这个代码,但它没有非常好的效果:
Right now I'm using this code, but it's does not have a very good performance:
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());
}
}
什么是最好的方式,将QImage转换为灰度?
What would be the best way, performance-wise, to convert a QImage to grayscale?
推荐答案
而不是使用 slow functions QImage :: pixel
和 QImage :: setPixel
,使用
QImage :: scanline
来访问数据。扫描(水平线)上的像素是连续的。假设你有一个32 bpp的图像,你可以使用QRgb迭代扫描。最后总是把x坐标放在内循环中。其中:
Rather than using the slow functions QImage::pixel
and QImage::setPixel
, use
QImage::scanline
to access the data. Pixels on a scan (horizontal line ) are consecutive. Assuming you have a 32 bpp image, you can use QRgb to iterate over the scan. Finally always put the x coordinate in the inner loop. Which gives :
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();
}
}
3585 x 2386图片
A quick test with an 3585 x 2386 image gave
********* Start testing of TestImage *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : TestImage::initTestCase()
RESULT : TestImage::grayscaleOp():
390 msecs per iteration (total: 390, iterations: 1)
PASS : TestImage::grayscaleOp()
RESULT : TestImage::grayscaleFast():
125 msecs per iteration (total: 125, iterations: 1)
PASS : TestImage::grayscaleFast()
PASS : TestImage::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped
********* Finished testing of TestImage *********
源代码:
testimage.h文件:
Source code: testimage.h file:
#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
testimage.cpp档案:
testimage.cpp file:
#include "testimage.h"
TestImage::TestImage(QObject *parent)
: QObject(parent)
, imgop("path_to_test_image.png")
, imgfast("path_to_test_image.png")
{
}
void TestImage::grayscaleOp()
{
QBENCHMARK
{
QImage& image = imgop;
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());
}
}
}
}
void TestImage::grayscaleFast()
{
QBENCHMARK {
QImage& image = imgfast;
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();
}
}
}
}
QTEST_MAIN(TestImage)
专业文件:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QImageTest
TEMPLATE = app
CONFIG += qtestlib
SOURCES += testimage.cpp
HEADERS += testimage.h
重要注意事项:
Important note:
- 通过反转环路。在这个测试案例中,它是
〜90ms
。 - 您可以使用其他库如opencv进行灰度转换,从opencv缓冲区。我期望更好的性能改进。
这篇关于将QImage转换为灰度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!