图像处理亮度调节
2017-01-02 19:25:00 weixin_30344995 阅读数 8

  在Android中提供了不同的通道对图片的色相、饱和度、亮度值进行修改,并且进行其中一个修改的时候不会影响其他的值。因此可以将三种调节的代码放到同一个方法中。

  下面是具体的代码:

	/**
	 * @param bm
	 * @param hue 色相
	 * @param saturation 饱和度
	 * @param lum 亮度
	 * @return
	 */
	public static Bitmap ImageEffect(Bitmap bm,float hue,float saturation,float lum){

		Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(),bm.getHeight(),Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);

		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		
		//色相调节
		ColorMatrix hueMatrix = new ColorMatrix();
		hueMatrix.setRotate(0, hue);
		hueMatrix.setRotate(1, hue);
		hueMatrix.setRotate(2, hue);

		//饱和度调节
		ColorMatrix saturationColorMatrix = new ColorMatrix();
		saturationColorMatrix.setSaturation(saturation);

		//亮度调节
		ColorMatrix lumMatrix = new ColorMatrix();
		lumMatrix.setScale(lum, lum, lum, 1);

		ColorMatrix ImageMatrix = new ColorMatrix();
		ImageMatrix.postConcat(hueMatrix);
		ImageMatrix.postConcat(saturationColorMatrix);
		ImageMatrix.postConcat(lumMatrix);

		paint.setColorFilter(new ColorMatrixColorFilter(ImageMatrix));
		canvas.drawBitmap(bm, 0, 0, paint);

		return bitmap;
	}
  调用的时候用seekbar获取调节的参数:

方法如下:

	//调节seekbar的值
	private final class FliterClick3 implements OnSeekBarChangeListener{

		@Override
		public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
			switch (seekBar.getId()) {
			case 0://色相
				Pix[0] = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180;
				ProcessingImage task1 = new ProcessingImage();
				task1.execute(0,7);
				break;
			case 1://饱和度
				Pix[1] = progress * 1.0F / MID_VALUE;
				ProcessingImage task2 = new ProcessingImage();
				task2.execute(0,7);
				break;				
			case 2://亮度
				Pix[2] = progress * 1.0F / MID_VALUE;
				ProcessingImage task3 = new ProcessingImage();
				task3.execute(0,7);
				break;
			}		
		}	

		@Override
		public void onStartTrackingTouch(SeekBar arg0) {

		}

		@Override
		public void onStopTrackingTouch(SeekBar arg0) {

		}

	}
  其中Pix是一个整型数组,用来存放seekBar的值。

  值得注意的是在实例化seekBar的时候要设置其最大值。

  调节的效果如下:

色相调节:


饱和度调节:


亮度调节:



这里我只调了几个数值,其实还可以联合调节的。

转载于:https://www.cnblogs.com/kaipingzhou/p/7589036.html

2019-07-21 12:36:01 u012292754 阅读数 7

1 色彩调节

  • ColorAdjustFilter
package demo2.coloradjust;

import demo2.utils.AbstractImageOptionFilter;

import java.awt.image.BufferedImage;

public class ColorAdjustFilter extends AbstractImageOptionFilter {

    private float minValue;
    private float maxValue;
    private float defaultMinValue;
    private float defaultMaxValue;
    private float bvalue;
    private int[] lut;
    private boolean minmax;
    public ColorAdjustFilter() {
        defaultMinValue = 0;
        defaultMaxValue = 255;
        minValue = 0;
        maxValue = 255;
        bvalue = 20;
        minmax = true;
    }

    public void setBvalue(float bvalue) {
        this.bvalue = bvalue;
    }

    public void setMinmax(boolean minmax) {
        this.minmax = minmax;
    }

    public void setMinValue(float minValue) {
        this.minValue = minValue;
    }

    public void setMaxValue(float maxValue) {
        this.maxValue = maxValue;
    }

    @Override
    public BufferedImage process(BufferedImage src) {
        int width = src.getWidth();
        int height = src.getHeight();
        int[] pixels = new int[width * height];
        getRGB(src, 0, 0, width, height, pixels);
        int index = 0;
        if(minmax) {
            setupMinMaxLut();
        }
        else {
            setupBrightnessLut();
        }
        for (int row = 0; row < height; row++) {
            for (int col = 0; col < width; col++) {
                index = row * width + col;
                int pixel = pixels[index];
                int ta = (pixel >> 24) & 0xff; // Alpha
                int tr = (pixel >> 16) & 0xff; // red
                int tg = (pixel >> 8) & 0xff; // green
                int tb = (pixel) & 0xff; // blue

                pixels[index] = (ta << 24 | lut[tr] << 16 | lut[tg] << 8 | lut[tb]);
            }
        }
        setRGB(src, 0, 0, width, height, pixels);
        return src;
    }

    public void setupMinMaxLut() {
        float min = defaultMinValue + minValue*(defaultMaxValue-defaultMinValue)/255;
        float max = defaultMinValue + maxValue*(defaultMaxValue-defaultMinValue)/255;
        System.out.println("min : " + min + ", max : " + max);
        lut = new int[256];
        for(int i=0; i<256; i++) {
            float v1 = (i - min);
            float delta = max - min;
            int v = (int)((v1 / delta) * 256);
            if(v < 0) {
                v = 0;
            }
            if(v > 255) {
                v = 255;
            }
            lut[i] = v;
        }
    }

    public void setupBrightnessLut() {
        float center = defaultMinValue + (defaultMaxValue-defaultMinValue)*((256-bvalue)/256);
        float min = defaultMinValue + minValue*(defaultMaxValue-defaultMinValue)/255;
        float max = defaultMinValue + maxValue*(defaultMaxValue-defaultMinValue)/255;
        float delta= max-min;
        min = center - delta/2.0f;
        max = center + delta/2.0f;

        System.out.println("min : " + min + ", max : " + max);
        lut = new int[256];
        for(int i=0; i<256; i++) {
            float v1 = (i - min);
            float delta2 = max - min;
            int v = (int)((v1 / delta2) * 256);
            if(v < 0) {
                v = 0;
            }
            if(v > 255) {
                v = 255;
            }
            lut[i] = v;
        }
    }


}

  • ImagePanel
package demo2.coloradjust;

import demo2.rgbspace.WhiteImageFilter;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ImagePanel extends JComponent implements ActionListener {

    private BufferedImage image;

    private JButton processBtn;

    public ImagePanel(BufferedImage image) {
        this.image = image;
    }

    public JButton getButton() {
        processBtn = new JButton("按钮");
        processBtn.addActionListener(this);

        return processBtn;
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        if (null != image) {
            g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
        }
    }

    public void process() {
        ColorAdjustFilter tool = new ColorAdjustFilter();
        tool.setMinValue(20);

        tool.process(image);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == processBtn) {
            this.process();
            this.repaint();
        }
    }


    public static void main(String[] args) {
        File file = new File("resource/color.png");

        try {
            BufferedImage image = ImageIO.read(file);

            ImagePanel imp = new ImagePanel(image);
            JFrame frame = new JFrame();
            frame.getContentPane().add(imp, BorderLayout.CENTER);
            frame.getContentPane().add(imp.getButton(), BorderLayout.SOUTH);
            frame.setSize(600, 600);
            frame.setTitle("图像显示测试");
            frame.setVisible(true);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

在这里插入图片描述

2 亮度调整

在这里插入图片描述

2018-08-08 13:01:13 u012366767 阅读数 676

    WPF图像处理程序,包括亮度、饱和度、对比度、Gamma调节,程序是从Delphi代码翻译过来的。

 

// Lightness Adjust
        public static void BitmapLightnessAdjust(Bitmap curBitmap, int width, int height, int delta)
        {
            if (delta == 0)
            {
                return;
            }
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = width * height * 4;
            byte[] rgbValues = new byte[bytes];
            Marshal.Copy(ptr, rgbValues, 0, bytes);
            if (delta > 0)
            {
                for (int i = 0; i < rgbValues.Length; i = i + 4)
                {
                    rgbValues[i] = (byte)Math.Min(255, rgbValues[i] + delta);
                    rgbValues[i + 1] = (byte)Math.Min(255, rgbValues[i + 1] + delta);
                    rgbValues[i + 2] = (byte)Math.Min(255, rgbValues[i + 2] + delta);
                }
            }
            else
            {
                for (int i = 0; i < rgbValues.Length; i = i + 4)
                {
                    rgbValues[i] = (byte)Math.Max(0, rgbValues[i] + delta);
                    rgbValues[i + 1] = (byte)Math.Max(0, rgbValues[i + 1] + delta);
                    rgbValues[i + 2] = (byte)Math.Max(0, rgbValues[i + 2] + delta);
                }
            }
            Marshal.Copy(rgbValues, 0, ptr, bytes);
            curBitmap.UnlockBits(bmpData);
        }

        // Saturation Adjust
        public static void BitmapSaturationAdjust(Bitmap curBitmap, int width, int height, int delta)
        {
            if (delta == 0)
            {
                return;
            }
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = width * height * 4;
            byte[] rgbValues = new byte[bytes];
            Marshal.Copy(ptr, rgbValues, 0, bytes);
            for (int i = 0; i < rgbValues.Length; i = i + 4)
            {
                if (rgbValues[i] > 128)
                {
                    rgbValues[i] = (byte)Math.Min(255, rgbValues[i] + delta);
                }
                else
                {
                    rgbValues[i] = (byte)Math.Max(0, rgbValues[i] - delta);
                }
                if (rgbValues[i + 1] > 128)
                {
                    rgbValues[i + 1] = (byte)Math.Min(255, rgbValues[i + 1] + delta);
                }
                else
                {
                    rgbValues[i + 1] = (byte)Math.Max(0, rgbValues[i + 1] - delta);
                }
                if (rgbValues[i + 2] > 128)
                {
                    rgbValues[i + 2] = (byte)Math.Min(255, rgbValues[i + 2] + delta);
                }
                else
                {
                    rgbValues[i + 2] = (byte)Math.Max(0, rgbValues[i + 2] - delta);
                }
            }
            Marshal.Copy(rgbValues, 0, ptr, bytes);
            curBitmap.UnlockBits(bmpData);
        }

        // Contrast Adjust
        public static void BitmapContrastAdjust(Bitmap curBitmap, int width, int height, int delta)
        {
            if (delta == 0)
            {
                return;
            }
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = width * height * 4;
            byte[] rgbValues = new byte[bytes];
            Marshal.Copy(ptr, rgbValues, 0, bytes);
            if (delta > 0)
            {
                for (int i = 0; i < rgbValues.Length; i = i + 4)
                {
                    if (rgbValues[i] > 128 && rgbValues[i + 1] > 128 && rgbValues[i + 2] > 128)
                    {
                        rgbValues[i] = (byte)Math.Min(255, rgbValues[i] + delta);
                        rgbValues[i + 1] = (byte)Math.Min(255, rgbValues[i + 1] + delta);
                        rgbValues[i + 2] = (byte)Math.Min(255, rgbValues[i + 2] + delta);
                    }
                    if (rgbValues[i] < 128 && rgbValues[i + 1] < 128 && rgbValues[i + 2] < 128)
                    {
                        rgbValues[i] = (byte)Math.Max(0, rgbValues[i] - delta);
                        rgbValues[i + 1] = (byte)Math.Max(0, rgbValues[i + 1] - delta);
                        rgbValues[i + 2] = (byte)Math.Max(0, rgbValues[i + 2] - delta);
                    }
                }
            }
            else
            {
                for (int i = 0; i < rgbValues.Length; i = i + 4)
                {
                    if (rgbValues[i] > 128 && rgbValues[i + 1] > 128 && rgbValues[i + 2] > 128)
                    {
                        rgbValues[i] = (byte)Math.Max(128, rgbValues[i] + delta);
                        rgbValues[i + 1] = (byte)Math.Max(128, rgbValues[i + 1] + delta);
                        rgbValues[i + 2] = (byte)Math.Max(128, rgbValues[i + 2] + delta);
                    }
                    if (rgbValues[i] < 128 && rgbValues[i + 1] < 128 && rgbValues[i + 2] < 128)
                    {
                        rgbValues[i] = (byte)Math.Min(128, rgbValues[i] - delta);
                        rgbValues[i + 1] = (byte)Math.Min(128, rgbValues[i + 1] - delta);
                        rgbValues[i + 2] = (byte)Math.Min(128, rgbValues[i + 2] - delta);
                    }
                }
            }
            Marshal.Copy(rgbValues, 0, ptr, bytes);
            curBitmap.UnlockBits(bmpData);
        }

        // Gamma Adjust
        public static void BitmapGammaAdjust(Bitmap curBitmap, int width, int height, double delta)
        {
            if (delta == 1)
            {
                return;
            }
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = width * height * 4;
            byte[] rgbValues = new byte[bytes];
            Marshal.Copy(ptr, rgbValues, 0, bytes);
            for (int i = 0; i < rgbValues.Length; i = i + 4)
            {
                rgbValues[i] = (byte)Math.Min(255, (int)Math.Round(255 * Math.Pow(rgbValues[i] / 255.0, delta)));
                rgbValues[i + 1] = (byte)Math.Min(255, (int)Math.Round(255 * Math.Pow(rgbValues[i + 1] / 255.0, delta)));
                rgbValues[i + 2] = (byte)Math.Min(255, (int)Math.Round(255 * Math.Pow(rgbValues[i + 1] / 255.0, delta)));
            }
            Marshal.Copy(rgbValues, 0, ptr, bytes);
            curBitmap.UnlockBits(bmpData);
        }

 

2017-07-19 17:32:33 llh_1178 阅读数 7276

处理图像经常会对图像色彩进行增强,这就是改变图像的亮度和对比度。本章基于opencv对图像的亮度和对比度进行处理操作。其实,这是对图像的每一个像素点进行相应的操作。


上面这个公式可以很好的解释对图像的亮度和对比度操作的原理,第一个参数α必须是大于零,不然则基本上没有意义了。α能代表什么呢?α能使图像像素成倍数的增长或降低(α<1),改变了是图像的对比度,因为使图像的差值变化了。那么β作何解释呢?β可为负,也可为正,那么任何一个像素都在(0, 255)之间,加上一个值或减去一个值则会使这个像素点变大或变小,其实就是向白色或向黑色靠近(0为黑,255为白),所以改变的是图像的亮度。

接下来我们用代码演示:

(一)基于Python语言——演示灰色图像的比色度和反差

import cv2
import matplotlib.pyplot as plt
# 反差与对比度
input_image = cv2.imread("Peppers.jpg")
output_gray = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
output_min_gray = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
output_max_gray = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
# 反差图像,cv2.bitwise_not()函数相当于用255减去每一个像素。
output_contrast_image = cv2.bitwise_not(input_image)
for i in xrange(input_image.shape[0]):
    for j in xrange(input_image.shape[1]):
        b = input_image[i, j, 0]
        g = input_image[i, j, 1]
        r = input_image[i, j, 2]
        output_min_gray[i, j] = min(b, min(g, r))
        output_max_gray[i, j] = max(b, min(g, r))

output_image = [output_gray, output_min_gray, output_max_gray, output_contrast_image]
output_titles = ["output_gray", "output_min_gray", "output_max_gray", "output_contrast_image"]
for i in xrange(4):
    plt.subplot(2, 2, (i+1))
    plt.imshow(output_image[i], "gray")
    plt.title(output_titles[i])
    plt.xticks([]), plt.yticks([])
plt.savefig("contrast_gray")


(二)基于C++语言——演示图像的亮度

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;

int main(int argc, char* argv) {
	Mat src, dst;
	src = imread("test.jpg");
	if (src.empty()) {
		printf("Could not load image...\n");
		return -1;
	}
	char input_win[] = "input image";
	namedWindow(input_win, CV_WINDOW_AUTOSIZE);
	imshow("input window", src);

	int height = src.rows;
	int width = src.cols;
	dst = Mat::zeros(src.size(), src.type());
        float alpha = 0.8;
	float beta = -20;
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			
			float b = src.at<Vec3b>(row, col)[0];
			float g = src.at<Vec3b>(row, col)[1];
			float r = src.at<Vec3b>(row, col)[2];
			// saturate_cast 函数确保像素值在0到255之间。
			dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
			dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);
			dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
			
		}
	}
	char output_title[] = "contrast and brightness change demo";
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	imshow(output_title, dst);
	
	waitKey(0);
	return 0;
}




2017-05-07 17:13:49 u013085897 阅读数 6406

       图像处理中,图像亮度调节可能是最简单的算法了,非常常见的线性运算即可完成亮度调节,比如所有像素点亮度值乘或者加一个增强系数,使得图像整体变亮或者变暗。看过一些相关开源代码,常见的操作是乘以一个亮度调节系数。但是,这样做很容易使图像出现过饱和现象,即亮度值超出255。photoshop中是如何实现的不得而知,每个版本可能也不一样。还是说说我的实现方法,其实就是在调节过程中,根据像素点亮度,做非线性调节,即高光、阴影部分调节小一点,中间部分多调节一些,这样亮度调节看着更自然一些。下面是示例代码:

void ImageBrightness(BMPINFO *pSrcBitmap, float strength)
{
	int brightness = (int)(strength*100);
	uchar lookupTable[256];
	for (int i = 0; i < 256; i++)
	{
		lookupTable[i] = (uchar)MIN(255, MAX(0, i + sin(FILTER_PI*i / 255.0f)*brightness));
	}

	int size = pSrcBitmap->lWidth*pSrcBitmap->lHeight;
	uchar* pSrcData = pSrcBitmap->pPlane[0];
	for (int i = 0; i < size; i++, pSrcData+=4)
	{
		pSrcData[AXJ_BLUE] = lookupTable[pSrcData[AXJ_BLUE]];
		pSrcData[AXJ_GREEN] = lookupTable[pSrcData[AXJ_GREEN]];
		pSrcData[AXJ_RED] = lookupTable[pSrcData[AXJ_RED]];
	}
}

       亮度调节示例图片,上面为原图,下面为结果图。

              

              




没有更多推荐了,返回首页