Qt 图像处理之 灰度变换

对图像的亮度、对比度进行变换是很常用的一种图像处理操作,但是Qt 本身却没有提供相应的功能代码。因此我写了个简单的类来实现这些操作。我把这个类称为 BrightnessMapper

 

代码如下:

#ifndef BRIGHTNESSMAPPER_H
#define BRIGHTNESSMAPPER_H
#include <QImage>

class BrightnessMapper
{
public:
    BrightnessMapper();
    ~BrightnessMapper();
    void setRedMap(unsigned char red[]);
    void setGreenMap(unsigned char green[]);
    void setBlueMap(unsigned char blue[]);
    void setMap(unsigned char map[]);
    void updateBCG(double brightness, double contrast, double gamma);
    void setColorMap(unsigned char red[], unsigned char green[], unsigned char blue[]);
    void apply(const QImage &from, QImage &to);
    QImage apply(const QImage &from);
    unsigned char *redMap(){ return m_red;}
    unsigned char *blueMap(){return m_blue;}
    unsigned char *greenMap(){return m_green;}
    void redMap(double red[256]);
    void greenMap(double green[256]);
    void blueMap(double blue[256]);
private:
    unsigned char m_red[256];
    unsigned char m_green[256];
    unsigned char m_blue[256];
};

#endif // BRIGHTNESSMAPPER_H

#include "brightnessmapper.h"
#include <math.h>
#include <QDebug>
BrightnessMapper::BrightnessMapper()
{
    for(int i = 0; i < 256; i++)
    {
        m_red[i] = i;
        m_green[i] = i;
        m_blue[i] = i;
    }
}

BrightnessMapper::~BrightnessMapper()
{

}

void BrightnessMapper::updateBCG(double brightness, double contrast, double gamma)
{
    double x, y;
    for(int i = 0; i < 256; i ++)
    {
        x = i / 255.0;
        y = exp(log(x) * gamma);
        y = (y - 0.5) * brightness + 0.5 + contrast / 255;
        y = y * 255.0;
        m_red[i] = qBound(0.0, y, 255.0);
        m_green[i] = m_red[i];
        m_blue[i] = m_red[i];

    }
}

QImage BrightnessMapper::apply(const QImage &from)
{
    QImage to = from;
    apply(from, to);
    return to;
}

void BrightnessMapper::apply(const QImage &from, QImage &to)
{
    if(to.size() != from.size() || to.format()!= from.format())
    {
        to = from.copy();
    }
    int height = from.height();
    int width = from.width();
    switch(from.format())
    {
    case QImage::Format_Indexed8:
        for(int i = 0; i < height; i++)
        {
            const uchar *pFrom = (const uchar *)from.constScanLine(i);
            uchar *pTo = (uchar *)to.scanLine(i);
            for(int j = 0; j < width; j++)
            {
                pTo[j] = m_red[pFrom[i]];
            }
        }
        break;
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        for(int i = 0; i < height; i++)
        {
            const QRgb *pFrom = (const QRgb *)from.constScanLine(i);
            QRgb *pTo = (QRgb *)to.scanLine(i);
            for(int j = 0; j < width; j++)
            {
                int r, g, b;
                r = qRed(pFrom[j]);
                g = qGreen(pFrom[j]);
                b = qBlue(pFrom[j]);
                r = m_red[r];
                g = m_green[g];
                b = m_blue[b];
                pTo[j] = qRgb(r, g, b);
            }
        }
        break;
    }
}
void BrightnessMapper::setRedMap(unsigned char red[])
{
    for(int i = 0; i < 256; i++)
    {
        m_red[i] = red[i];
    }
}

void BrightnessMapper::setGreenMap(unsigned char green[])
{
    for(int i = 0; i < 256; i++)
    {
        m_green[i] = green[i];
    }
}

void BrightnessMapper::setBlueMap(unsigned char blue[])
{
    for(int i = 0; i < 256; i++)
    {
        m_blue[i] = blue[i];
    }
}

void BrightnessMapper::setMap(unsigned char map[])
{
    for(int i = 0; i < 256; i++)
    {
        m_red[i] = map[i];
        m_green[i] = map[i];
        m_blue[i] = map[i];
    }
}

void BrightnessMapper::setColorMap(unsigned char red[], unsigned char green[], unsigned char blue[])
{
    for(int i = 0; i < 256; i++)
    {
        m_red[i] = red[i];
        m_green[i] = green[i];
        m_blue[i] = blue[i];
    }
}
void BrightnessMapper::redMap(double red[256])
{
    for(int i = 0; i < 256; i++)
    {
        red[i] = m_red[i];
    }
}

void BrightnessMapper::greenMap(double green[256])
{
    for(int i = 0; i < 256; i++)
    {
        green[i] = m_green[i];
    }
}

void BrightnessMapper::blueMap(double blue[256])
{
    for(int i = 0; i < 256; i++)
    {
        blue[i] = m_blue[i];
    }
}

这个类的用法很简单。可以用下面几个函数来设置灰度变换关系。

 

void setRedMap(unsigned char red[]);

void setGreenMap(unsigned char green[]);

void setBlueMap(unsigned char blue[]);

void setMap(unsigned char map[]);

void setColorMap(unsigned char red[], unsigned char green[], unsigned char blue[]);

 

也可以用下面这个函数通过设置亮度、对比度、gamma 值来确定变换关系。

void updateBCG(double brightness, double contrast, double gamma);

 

变换关系确定后可以利用下面两个函数之一来对图像进行变换处理。

void apply(const QImage &from, QImage &to);

QImage apply(const QImage &from);

 

还有几个辅助函数可以用来读取变换关系表。

unsigned char *redMap(){ return m_red;}

unsigned char *blueMap(){return m_blue;}

unsigned char *greenMap(){return m_green;}

void redMap(double red[256]);

void greenMap(double green[256]);

void blueMap(double blue[256]);

 

因为代码很简答,就不多介绍了。希望对大家有用。

 


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值