「java灰度变换」灰度变换流程图

博主:adminadmin 2023-03-17 05:50:07 299

本篇文章给大家谈谈java灰度变换,以及灰度变换流程图对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

求一个JAVA方法 要求计算RGB32位模式的颜色转换为灰度 小弟对色彩和图形不是很懂。谢谢

public static final byte[] getPixels(Image img)

{

if (img == null)

return null ;

int width = img.getWidth(null) ;

int height = img.getHeight(null) ;

BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_BYTE_GRAY) ;

bi.getGraphics().drawImage(img,0,0,null) ;

ByteArrayOutputStream bos = new ByteArrayOutputStream();

try

{

ImageIO.write(bi, "png", bos);

} catch (IOException ex)

{

}

return bos.toByteArray() ;

}

java中图像与数组转换

按照你的要求编写的Java程序如下:( 要注意的地方见语句后面的注释)

import java.awt.image.BufferedImage;

import java.awt.image.RenderedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageWithArray {

 public static void main(String[] args) {

  // 读取图片到BufferedImage

  BufferedImage bf = readImage("c:\\tmp\\6\\female.png");//这里写你要读取的绝对路径+文件名

  // 将图片转换为二维数组

  int[][] rgbArray1 = convertImageToArray(bf);

  // 输出图片到指定文件

  writeImageFromArray("c:\\tmp\\2.png", "png", rgbArray1);//这里写你要输出的绝对路径+文件名

  System.out.println("图片输出完毕!");

 }

 public static BufferedImage readImage(String imageFile){

  File file = new File(imageFile);

  BufferedImage bf = null;

  try {

   bf = ImageIO.read(file);

  } catch (IOException e) {

   e.printStackTrace();

  }

  return bf;

 }

 public static int[][] convertImageToArray(BufferedImage bf) {

  // 获取图片宽度和高度

  int width = bf.getWidth();

  int height = bf.getHeight();

  // 将图片sRGB数据写入一维数组

  int[] data = new int[width*height];

  bf.getRGB(0, 0, width, height, data, 0, width);

  // 将一维数组转换为为二维数组

  int[][] rgbArray = new int[height][width];

  for(int i = 0; i  height; i++)

   for(int j = 0; j  width; j++)

    rgbArray[i][j] = data[i*width + j];

  return rgbArray;

 }

 public static void writeImageFromArray(String imageFile, String type, int[][] rgbArray){

  // 获取数组宽度和高度

  int width = rgbArray[0].length;

  int height = rgbArray.length;

  // 将二维数组转换为一维数组

  int[] data = new int[width*height];

  for(int i = 0; i  height; i++)

   for(int j = 0; j  width; j++)

    data[i*width + j] = rgbArray[i][j];

  // 将数据写入BufferedImage

  BufferedImage bf = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);

  bf.setRGB(0, 0, width, height, data, 0, width);

  // 输出图片

  try {

   File file= new File(imageFile);

   ImageIO.write((RenderedImage)bf, type, file);

  } catch (IOException e) {

   e.printStackTrace();

  }

 }

}

运行结果:

图片输出完毕!

原图:

输出图:

OpenCV (一)Mat基本操作以及灰度图转化

开始写OpenCV这篇文章的时候,不由想到,我的大学计算机图形学的第一门实操课程就是灰度转化,拉普拉斯锐化等。其中灰度图的转化,是计算机图形学基础中基础,这里就顺着OpenCV的灰度的转化,来看看OpenCV一些基础的api。

本文地址:

先来看看OpenCV,基础对象Mat,矩阵。什么是矩阵,实际上没有必要解释,一般人都能够明白数学意义上矩阵的含义。

OpenCV把每一个M * N的宽高图像,看成M*N的矩阵。矩阵的每一个单元就对应着图像中像素的每一个点。

我们如果放大图中某个部分,就会发现如下情况

图像实际上就如同矩阵一样每个单元由一个像素点构成。

因为OpenCV的Mat每一个像素点,包含的数据不仅仅只有一个单纯的数字。每一个像素点中包含着颜色通道数据。

稍微解释一下颜色通道,我们可以把世间万物肉眼能识别的颜色由3种颜色(R 红色,G 绿色,B 蓝色)经过调节其色彩饱和度组成的。也就是说通过控制RGB三种的色值大小(0~255)来调配新的颜色。

当我们常见的灰度图,一般是单个颜色通道,因为只用黑白两种颜色。我们常见的图片,至少是三色通道,因为需要RGB三种颜色通道。

我们常见Android的Bitmap能够设置ARGB_8888的标志位就是指能够通过A(透明通道),R,G,B来控制图片加载的颜色通道。

OpenCV为了更好的控制这些数据。因此采用了数学上的矩阵的概念。当OpenCV要控制如RGB三色通道的Mat,本质上是一个M * N * 3的三维矩阵。

但是实际上,我们在使用OpenCV的Mat的时候,我们只需要关注每个图片的像素,而每个像素的颜色通道则是看成Mat中每个单元数据的内容即可

我们先来看看Mat的构造方法

现阶段,实际上我们值得我们注意的是构造函数:

举个例子:

这个mat矩阵将会制造一个高20,宽30,一个1字节的颜色通道(也是Mat中每一个像素数据都是1字节的unchar类型的数据),同时颜色是白色的图片。

在这里面我们能够看到一个特殊的宏CV_8UC1。实际上这是指代OpenCV中图片带的是多少颜色通道的意思。

这4个宏十分重要,要时刻记住。

当我们需要把Mat 中的数据拷贝一份出来,我们应该调用下面这个api:

这样就能拷贝一份像素数据到新的Mat中。之后操作新的Mat就不会影响原图。

实际上,在本文中,我们能够看到OpenCV是这么调用api读取图片的数据转化为Mat矩阵。

OpenCV会通过imread去读图片文件,并且转化为Mat矩阵。

能看见imread,是调用imread_把图片中的数据拷贝的img这个Mat对象中。接着会做一次图片的颠倒。这个方面倒是和Glide很相似。

文件:modules/imgcodecs/src/loadsave.cpp

这里面做了几个事情,实际上和FFmpge的设计十分相似。

其核心也是操作Mat中的像素指针,找到颜色通道,确定指针移动的步长,赋值图片的数据到Mat矩阵中。核心如下:

其中还涉及到jpeg的哈夫曼算法之类的东西,这里就不深入源码。毕竟这是基础学习。

什么是灰度图,灰度度图实际上我们经常见到那些灰白的也可以纳入灰度图的范畴。实际上在计算机图形学有这么一个公式:

将RGB的多颜色图,通过 的算法,将每一个像素的图像的三颜色通道全部转化为为一种色彩,通过上面的公式转为为一种灰色的颜色。

一旦了解了,我们可以尝试编写灰度图的转化。我们通过矩阵的at方法访问每一个像素中的数据。

为了形象表示矩阵指针,指向问题,可以把RGB在OpenCV的Mat看成如下分布:

记住OpenCV的RGB的顺序和Android的不一样,是BGRA的顺序。和我们Android开发颠倒过来。

因此,我们可以得到如下的例子

我们经过尝试之后,确实能够把一个彩色的图片转化一个灰色图片。但是这就是

这里介绍一下Mat的一个api:

实际上OpenCV,内置了一些操作,可以把RGB的图像数据转化灰度图。

我们看看OpenCV实际上的转化出来的灰度图大小。我们通过自己写的方法,转化出来的灰度图是119kb,而通过cvtColor转化出来的是44kb。

问题出在哪里?还记得吗?因为只有灰白两种颜色,实际上只需要一种颜色通道即可,而这边还保留了3个颜色通道,也就说图片的每一个像素点中的数据出现了没必要的冗余。

这样就是44kb的大小。把三颜色通道的数据都设置到单颜色通道之后,就能进一步缩小其大小。

实际上在Android中的ColorMatrix中也有灰度图转化的api。

对画笔矩阵进行一次,矩阵变化操作。

实际上就是做了一次矩阵运算。绘制灰度的时候相当于构建了这么一个矩阵

接着通过矩阵之间的相乘,每一行的 0.213f,0.715f,0.072f控制像素的每个通道的色值。

对于Java来说,灰度转化的算法是: ,把绿色通道的比例调大了。

在OpenCV中有这么两个API,add和addWidget。两者都是可以把图像混合起来。

add和addWidget都是将像素合并起来。但是由于是像素直接相加的,所以容易造成像素接近255,让整个像素泛白。

而权重addWeighted,稍微能减轻一点这种问题,本质上还是像素相加,因此打水印一般不是使用这种办法。

等价于

saturate_cast这个是为了保证计算的值在0~255之间,防止越界。

饱和度,图片中色值更加大,如红色,淡红,鲜红

对比度:是指图像灰度反差。相当于图像中最暗和最亮的对比

亮度:暗亮度

控制对比度,饱和度的公式: , ,

因此当我们想要控制三通道的饱和度时候,可以通过alpha来控制色值成比例增加,beta控制一个色值线性增加。

如下:

在这里,看到了OpenCV会把所有的图片看成Mat矩阵。从本文中,能看到Mat的像素操作可以能看到有两种,一种是ptr像素指针,一种是at。ptr是OpenCV推荐的更加效率的访问速度。

当然还有一种LUT的核心函数,用来极速访问Mat矩阵中的像素。其原理是对着原来的色值进行预先的变换对应(设置一个颜色通道)。用来应对设置阈值等情况。

关于java灰度变换和灰度变换流程图的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。