web-dev-qa-db-ja.com

RGB画像の明るさを変更するアルゴリズム?

RGB->輝度にするための公式があることは知っていますが、画像のRGB値を変更するために明るさパラメーターを指定する必要があります。それ、どうやったら出来るの?

ありがとう

8
user1475859

RGBからHSL(色相/彩度/輝度)にマッピングし、色相と彩度を同じに保ち、輝度を変更してから、HSLからRGBへの逆方向マッピングを実行します。

RGBからHSLおよびHSLからRGBへの変換について詳しくはこちらをご覧ください。

17
Chris A.

最も簡単な方法は、R、G、Bの各値に定数を掛けることです。定数が1より大きい場合は明るくなり、1未満の場合は暗くなります。明るくする場合は、各値をテストして、最大値(通常は255)を超えないことを確認する必要があります。

これは、RGBからHSLに変換して元に戻すよりも単純であるだけでなく、物理オブジェクトに異なる量の光を当てたときに何が起こるかをより厳密に近似します。

17
Mark Ransom

私の推奨事項は ChrisA。 の答えと同じですが、1つの違いがあります。

代わりに HS[〜#〜] p [〜#〜]色空間 を使用してください。これはPhotoshopの近似値です。アルゴリズムとより良い結果があります。


HSPのサイトにリンクするだけでなく(率直に言って十分すぎるはずです。例なしで答えたくないだけです)、サイトの次のC#実装を次に示します。

#region Definitions
//Perceived brightness to Red ratio.
private const double Pr = .299;
//Perceived brightness to Green ratio.
private const double Pg = .587;
//Perceived brightness to Blue ratio.
private const double Pb = .114;
#endregion

//Expected ranges: Hue = 0-359... Other values = 0-1
public static ColorRGB ToRGB(double hue, double saturation, double perceivedBrightness, double alpha) {
    //Check values within expected range
    hue = hue < 0 ? 0 : hue > 359 ? 359 : hue;
    saturation = saturation < 0 ? 0 : saturation > 1 ? 1 : saturation;
    perceivedBrightness = perceivedBrightness < 0 ? 0 : perceivedBrightness > 1 ? 1 : perceivedBrightness;
    alpha = alpha < 0 ? 0 : alpha > 1 ? 1 : alpha;
    //Conversion
    var minOverMax = 1 - saturation;
    double r, g, b;
    if (minOverMax > 0) {
        double part;
        if (hue < 0.166666666666667D) { //R>G>B
            hue = 6 * (hue - 0); part = 1 + hue * (1 / minOverMax - 1);
            b = perceivedBrightness / Math.Sqrt(Pr / minOverMax / minOverMax + Pg * part * part + Pb);
            r = b / minOverMax; g = b + hue * (r - b);
        }
        else if (hue < 0.333333333333333D) { //G>R>B
            hue = 6 * (-hue + 0.333333333333333D); part = 1 + hue * (1 / minOverMax - 1);
            b = perceivedBrightness / Math.Sqrt(Pg / minOverMax / minOverMax + Pr * part * part + Pb);
            g = b / minOverMax; r = b + hue * (g - b);
        }
        else if (hue < 0.5D) {   //  G>B>R
            hue = 6 * (hue - 0.333333333333333D); part = 1 + hue * (1 / minOverMax - 1);
            r = perceivedBrightness / Math.Sqrt(Pg / minOverMax / minOverMax + Pb * part * part + Pr);
            g = r / minOverMax; b = r + hue * (g - r);
        }
        else if (hue < 0.666666666666667D) { //B>G>R
            hue = 6 * (-hue + 0.666666666666667D); part = 1 + hue * (1 / minOverMax - 1);
            r = perceivedBrightness / Math.Sqrt(Pb / minOverMax / minOverMax + Pg * part * part + Pr);
            b = r / minOverMax; g = r + hue * (b - r);
        }
        else if (hue < 0.833333333333333D) { //B>R>G
            hue = 6 * (hue - 0.666666666666667D); part = 1 + hue * (1 / minOverMax - 1);
            g = perceivedBrightness / Math.Sqrt(Pb / minOverMax / minOverMax + Pr * part * part + Pg);
            b = g / minOverMax; r = g + hue * (b - g);
        }
        else { //R>B>G
            hue = 6 * (-hue + 1D); part = 1 + hue * (1 / minOverMax - 1);
            g = perceivedBrightness / Math.Sqrt(Pr / minOverMax / minOverMax + Pb * part * part + Pg);
            r = g / minOverMax; b = g + hue * (r - g);
        }
    }
    else {
        if (hue < 0.166666666666667D) { //R>G>B
            hue = 6 * (hue - 0D); r = Math.Sqrt(perceivedBrightness * perceivedBrightness / (Pr + Pg * hue * hue)); g = r * hue; b = 0;
        }
        else if (hue < 0.333333333333333D) { //G>R>B
            hue = 6 * (-hue + 0.333333333333333D); g = Math.Sqrt(perceivedBrightness * perceivedBrightness / (Pg + Pr * hue * hue)); r = g * hue; b = 0;
        }
        else if (hue < 0.5D) { //G>B>R
            hue = 6 * (hue - 0.333333333333333D); g = Math.Sqrt(perceivedBrightness * perceivedBrightness / (Pg + Pb * hue * hue)); b = g * hue; r = 0;
        }
        else if (hue < 0.666666666666667D) { //B>G>R
            hue = 6 * (-hue + 0.666666666666667D); b = Math.Sqrt(perceivedBrightness * perceivedBrightness / (Pb + Pg * hue * hue)); g = b * hue; r = 0;
        }
        else if (hue < 0.833333333333333D) { //B>R>G
            hue = 6 * (hue - 0.666666666666667D); b = Math.Sqrt(perceivedBrightness * perceivedBrightness / (Pb + Pr * hue * hue)); r = b * hue; g = 0;
        }
        else { //R>B>G
            hue = 6 * (-hue + 1D); r = Math.Sqrt(perceivedBrightness * perceivedBrightness / (Pr + Pb * hue * hue)); b = r * hue; g = 0;
        }
    }
    return new ColorRGB(r, g, b, alpha);
}

//Expected ranges: 0-1 on all components
public static ColorHSP FromRGB(double red, double green, double blue, double alpha) {
    //Guarantee RGB values are in the correct ranges
    red = red < 0 ? 0 : red > 1 ? 1 : red;
    green = green < 0 ? 0 : green > 1 ? 1 : green;
    blue = blue < 0 ? 0 : blue > 1 ? 1 : blue;
    alpha = alpha < 0 ? 0 : alpha > 1 ? 1 : alpha;
    //Prepare & cache values for conversion
    var max = MathExtensions.Max(red, green, blue);
    var min = MathExtensions.Min(red, green, blue);
    var delta = max - min;
    double h, s, p = Math.Sqrt(0.299 * red + 0.587 * green + 0.114 * blue);
    //Conversion
    if (delta.Equals(0)) h = 0;
    else if (max.Equals(red)) {
        h = (green - blue) / delta % 6;
    }
    else if (max.Equals(green)) h = (blue - red) / delta + 2;
    else h = (red - green) / delta + 4;
    h *= 60;
    if (h < 0) h += 360;
    if (p.Equals(0))
        s = 0;
    else
        s = delta / p;
    //Result
    return new ColorHSP(h, s, p, alpha);
}
4
XenoRo

Mark Ransomの回答への追加:255定数で上記の係数を使用し、それを現在の色の値に追加することをお勧めします。

float brightnessFac = //between -1.0 and 1.0    
byte brightnessRed = red + (255f * brightnessFac);

0.0から1.0の間の係数で行う場合

byte brightnessRed = red * brightnessFac;

値0はゼロのままです。

2
patrickf
import Java.io.*;
import Java.awt.Color;
import javax.imageio.ImageIO;
import Java.io.*;
import Java.awt.image.BufferedImage;



    class psp{

public static void main(String a[]){
try{

File input=new File("abc.jpg");
File output=new File("output1.jpg");
        BufferedImage picture1 = ImageIO.read(input);   // original
BufferedImage picture2= new BufferedImage(picture1.getWidth(), picture1.getHeight(),BufferedImage.TYPE_INT_RGB);      
        int width  = picture1.getWidth();
        int height = picture1.getHeight();

int factor=50;
for (int y = 0; y < height ; y++) {//loops for images
for (int x = 0; x < width ; x++) {

Color c=new Color(picture1.getRGB(x,y));
int r=c.getRed()+factor;
int b=c.getBlue()+factor;
int g=c.getGreen()+factor;

if (r >= 256) {
    r = 255;
} else if (r < 0) {
r = 0;
}

if (g >= 256) {
g = 255;
} else if (g < 0) {
g = 0;
}

 if (b >= 256) {
b = 255;
} else if (b < 0) {
b = 0;
 }
picture2.setRGB(x, y,new Color(r,g,b).getRGB());


}
}




ImageIO.write(picture2,"jpg",output);       
}catch(Exception e){
System.out.println(e);
}





}




}
0
Tarun Rawat