Java DIP - 快速指南
Java DIP - 简介
数字图像处理 (DIP) 涉及使用数字计算机处理数字图像。它是信号与系统的一个子领域,但特别关注图像。DIP 专注于开发能够对图像进行处理的计算机系统。这种系统的输入是数字图像。系统使用有效的算法处理图像,并将图像作为输出。

Java 是一种在现代世界中广泛使用的高级编程语言。它可以使用各种函数有效地支持和处理数字图像处理。
Java BufferedImage 类
Java BufferedImage
类是 Image 类的子类。它用于处理和操作图像数据。BufferedImage
由图像数据的 ColorModel 组成。所有 BufferedImage
对象的左上角坐标均为 (0, 0)。
构造函数
此类支持三种类型的构造函数。
第一个构造函数使用指定的 ColorModel 和 Raster 构造一个新的 BufferedImage
。
BufferedImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable<?,?> properties)
第二个构造函数构造一个预定义图像类型之一的 BufferedImage
。
BufferedImage(int width, int height, int imageType)
第三个构造函数构造一个预定义图像类型之一的 BufferedImage
:TYPE_BYTE_BINARY或 TYPE_BYTE_INDEXED。
BufferedImage(int width, int height, int imageType, IndexColorModel cm)
Sr.No | 方法 &描述 |
---|---|
1 |
copyData(WritableRaster outRaster) 计算 |
2 |
getColorModel() 返回图像的 ColorModel 类对象。 |
3 |
getData() 将图像作为一个大图块返回。 |
4 |
getData(Rectangle rect) 它计算并返回 |
5 |
getGraphics() 此方法返回 Graphics2D,保留向后兼容性。 |
6 |
getHeight() 它返回 |
7 |
getMinX() 它返回此 |
8 |
getMinY() 它返回此 |
9 |
getRGB(int x, int y) 它返回默认 RGB 颜色模型 (TYPE_INT_ARGB) 和默认 sRGB 颜色空间中的整数像素。 |
10 |
getType() 它返回图像类型。 |
示例
以下示例演示了如何使用 java BufferedImage
类,该类使用 Graphics Object 在屏幕上绘制一些文本 −
import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import javax.swing.JFrame; import javax.swing.JPanel; public class Test extends JPanel { public void paint(Graphics g) { Image img = createImageWithText(); g.drawImage(img, 20,20,this); } private Image createImageWithText() { BufferedImage bufferedImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB); Graphics g = bufferedImage.getGraphics(); g.drawString("www.tutorialspoint.com", 20,20); g.drawString("www.tutorialspoint.com", 20,40); g.drawString("www.tutorialspoint.com", 20,60); g.drawString("www.tutorialspoint.com", 20,80); g.drawString("www.tutorialspoint.com", 20,100); return bufferedImage; } public static void main(String[] args) { JFrame frame = new JFrame(); frame.getContentPane().add(new Test()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); frame.setVisible(true); } }
输出
执行给定的代码时,将看到以下输出 −
下载和上传图片
在本章中,我们将了解如何从互联网上下载图片、对图片执行一些图片处理技术,然后再次将处理后的图片上传到服务器。
下载图片
为了从网站下载图片,我们使用名为 URL 的 Java 类,该类可在 java.net 包下找到。其语法如下 −
String website = "http://tutorialspoint.com"; URL url = new URL(website);
除了上述方法外,类 URL 中还有其他方法可用,如下所述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
public String getPath() 返回 URL 的路径。 |
2 |
public String getQuery() 返回 URL 的查询部分。 |
3 |
public String getAuthority() 返回 URL 的权限。 |
4 |
public int getPort() 它返回 URL 的端口。 |
5 |
public int getDefaultPort() 它返回 URL 协议的默认端口。 |
6 |
public String getProtocol() 它返回 URL 的协议。 |
7 |
public String getHost() 它返回URL。 |
示例
以下示例演示如何使用 java URL 类从互联网下载图像 −
import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; public class Download { public static void main(String[] args) throws Exception { try{ String fileName = "digital_image_processing.jpg"; String website = "http://tutorialspoint.com/java_dip/images/"+fileName; System.out.println("Downloading File From: " + website); URL url = new URL(website); InputStream inputStream = url.openStream(); OutputStream outputStream = new FileOutputStream(fileName); byte[] buffer = new byte[2048]; int length = 0; while ((length = inputStream.read(buffer)) != -1) { System.out.println("Buffer Read of length: " + length); outputStream.write(buffer, 0, length); } inputStream.close(); outputStream.close(); } catch(Exception e) { System.out.println("Exception: " + e.getMessage()); } } }
输出
执行上述命令时,将看到以下输出。
它将从服务器下载以下图像。

上传图像
让我们看看如何将图像上传到 Web 服务器。我们将 BufferedImage 转换为字节数组,以便将其发送到服务器。
我们使用 Java 类 ByteArrayOutputStream,该类可在 java.io 包下找到。其语法如下所示 −
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", baos);
为了将图像转换为字节数组,我们使用 ByteArrayOutputStream 类的 toByteArray() 方法。其语法如下所示 −
byte[] bytes = baos.toByteArray();
除了上述方法外,ByteArrayOutputStream 类中还有其他方法可用,如下所述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
public void reset() 此方法将字节数组输出流的有效字节数重置为零,以便丢弃流中累积的所有输出。 |
2 |
public byte[] toByteArray() 此方法创建一个新分配的字节数组。其大小将是输出流的当前大小,缓冲区的内容将被复制到其中。它将输出流的当前内容作为字节数组返回。 |
3 |
public String toString() 将缓冲区内容转换为字符串。将根据默认字符编码进行翻译。它返回从缓冲区内容翻译的字符串。 |
4 |
public void write(int w) 它将指定的数组写入输出流。 |
5 |
public void write(byte []b, int of, int len) 它将从偏移量 off 开始的 len 个字节写入流。 |
6 |
public void writeTo(OutputStream outSt) 它将此流的全部内容写入指定的流参数。 |
示例
以下示例演示了如何使用 ByteArrayOutputStream 将图像上传到服务器 −
Client Code
import javax.swing.*; import java.net.*; import java.awt.image.*; import javax.imageio.*; import java.io.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class Client{ public static void main(String args[]) throws Exception{ Socket soc; BufferedImage img = null; soc=new Socket("localhost",4000); System.out.println("Client is running. "); try { System.out.println("Reading image from disk. "); img = ImageIO.read(new File("digital_image_processing.jpg")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(img, "jpg", baos); baos.flush(); byte[] bytes = baos.toByteArray(); baos.close(); System.out.println("Sending image to server. "); OutputStream out = soc.getOutputStream(); DataOutputStream dos = new DataOutputStream(out); dos.writeInt(bytes.length); dos.write(bytes, 0, bytes.length); System.out.println("Image sent to server. "); dos.close(); out.close(); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); soc.close(); } soc.close(); } }
服务器代码
import java.net.*; import java.io.*; import java.awt.image.*; import javax.imageio.*; import javax.swing.*; class Server { public static void main(String args[]) throws Exception{ ServerSocket server=null; Socket socket; server = new ServerSocket(4000); System.out.println("Server Waiting for image"); socket = server.accept(); System.out.println("Client connected."); InputStream in = socket.getInputStream(); DataInputStream dis = new DataInputStream(in); int len = dis.readInt(); System.out.println("Image Size: " + len/1024 + "KB"); byte[] data = new byte[len]; dis.readFully(data); dis.close(); in.close(); InputStream ian = new ByteArrayInputStream(data); BufferedImage bImage = ImageIO.read(ian); JFrame f = new JFrame("Server"); ImageIcon icon = new ImageIcon(bImage); JLabel l = new JLabel(); l.setIcon(icon); f.add(l); f.pack(); f.setVisible(true); } }
输出
客户端输出
执行客户端代码时,客户端上会出现以下输出 −
服务器端输出
执行服务器代码时,服务器端会出现以下输出 −
收到图像后,服务器会显示如下图像 −
Java DIP - 图像像素
图像包含一个二维像素数组。它实际上是构成图像的那些像素的值。通常,图像可以是彩色的或灰度的。
在 Java 中,BufferedImage 类用于处理图像。您需要调用 BufferedImage 类的 getRGB() 方法来获取像素的值。
获取像素值
可以使用以下语法接收像素值−
Color c = new Color(image.getRGB(j, i));
获取 RGB 值
方法 getRGB() 将行和列索引作为参数并返回相应的像素。对于彩色图像,它返回三个值(红色、绿色、蓝色)。它们可以通过以下方式获取−
c.getRed(); c.getGreen(); c.getBlue();
获取图像的宽度和高度
可以通过调用BufferedImage类的getWidth()和getHeight()方法来获取图像的高度和宽度。其语法如下−
int width = image.getWidth(); int height = image.getHeight();
除了这些方法之外,BufferedImage类还支持其他方法。它们被简要描述−
Sr.No. | 方法 &描述 |
---|---|
1 |
copyData(WritableRaster outRaster) 计算 BufferedImage 的任意矩形区域并将其复制到指定的 WritableRaster 中。 |
2 |
getColorModel() 返回图像的 ColorModel。 |
3 |
getData() 将图像作为一个大图块返回。 |
4 |
getData(Rectangle rect) 它计算并返回 BufferedImage 的任意区域。 |
5 |
getGraphics() 此方法返回 Graphics2D,但在此用于向后兼容。 |
6 |
getHeight() 它返回 BufferedImage 的高度。 |
7 |
getMinX() 它返回此 BufferedImage 的最小 x 坐标。 |
8 |
getMinY() 它返回此 BufferedImage 的最小 y 坐标。 |
9 |
getRGB(int x, int y) 它返回默认 RGB 颜色模型 (TYPE_INT_ARGB) 和默认 sRGB 颜色空间中的整数像素。 |
10 |
getType() 它返回图像类型。 |
示例
以下示例演示了如何使用 java BufferedImage 类来显示大小为 (100 x 100) 的图像的像素 −
import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import javax.imageio.ImageIO; import javax.swing.JFrame; class Pixel { BufferedImage image; int width; int height; public Pixel() { try { File input = new File("blackandwhite.jpg"); image = ImageIO.read(input); width = image.getWidth(); height = image.getHeight(); int count = 0; for(int i=0; i<height; i++) { for(int j=0; j<width; j++) { count++; Color c = new Color(image.getRGB(j, i)); System.out.println("S.No: " + count + " Red: " + c.getRed() +" Green: " + c.getGreen() + " Blue: " + c.getBlue()); } } } catch (Exception e) {} } static public void main(String args[]) throws Exception { Pixel obj = new Pixel(); } }
输出
执行上述示例时,它将打印以下图像的像素 −
原始图像

像素输出
如果向下滚动输出,将看到以下模式−
Java DIP - 灰度转换
为了将彩色图像转换为灰度图像,您需要使用读取图像的像素或数据File 和 ImageIO 对象,并将图像存储在 BufferedImage 对象中。其语法如下 −
File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input);
此外,使用方法 getRGB() 获取像素值并对其执行 GrayScale() 方法。方法 getRGB() 将行和列索引作为参数。
Color c = new Color(image.getRGB(j, i)); int red = (c.getRed() * 0.299); int green =(c.getGreen() * 0.587); int blue = (c.getBlue() *0.114);
除了这三种方法之外,Color 类中还有其他方法,如下所述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
brighter() 它创建一个新的颜色,它是此颜色的更亮版本。 |
2 |
darker() 它创建一个新的颜色,它是此颜色的更暗版本。 |
3 |
getAlpha() 它返回 0-255 范围内的 alpha 分量。 |
4 |
getHSBColor(float h, float s, float b) 根据 HSB 颜色模型的指定值创建一个 Color 对象。 |
5 |
HSBtoRGB(float hue, float saturation, float bright) 将 HSB 模型指定的颜色成分转换为默认 RGB 模型的一组等效值。 |
6 |
toString() 返回此颜色的字符串表示形式颜色。 |
最后一步是将这三个值全部相加,然后再次将其设置为相应的像素值。其语法如下 −
int sum = red+green+blue; Color newColor = new Color(sum,sum,sum); image.setRGB(j,i,newColor.getRGB());
示例
以下示例演示了如何使用 Java BufferedImage 类将图像转换为灰度图像 −
import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import javax.imageio.ImageIO; import javax.swing.JFrame; public class GrayScale { BufferedImage image; int width; int height; public GrayScale() { try { File input = new File("digital_image_processing.jpg"); image = ImageIO.read(input); width = image.getWidth(); height = image.getHeight(); for(int i=0; i<height; i++) { for(int j=0; j<width; j++) { Color c = new Color(image.getRGB(j, i)); int red = (int)(c.getRed() * 0.299); int green = (int)(c.getGreen() * 0.587); int blue = (int)(c.getBlue() *0.114); Color newColor = new Color(red+green+blue, red+green+blue,red+green+blue); image.setRGB(j,i,newColor.getRGB()); } } File ouptut = new File("grayscale.jpg"); ImageIO.write(image, "jpg", ouptut); } catch (Exception e) {} } static public void main(String args[]) throws Exception { GrayScale obj = new GrayScale(); } }
输出
执行给定示例时,它会将图像 digital_image_processing.jpg 转换为其等效的灰度图像,并将其写入硬盘,名称为 grayscale.jpg。
原始图像

灰度图像

Java DIP - 增强图像对比度
在本章中学习如何使用直方图均衡化增强图像的对比度。
我们使用 OpenCV 函数 equalizeHist() 方法。它可以在 Imgproc 包下找到。其语法如下 −
Imgproc.equalizeHist(source, destination);
参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 它是 8 位单通道源图像。 |
2 |
destination 它是目标图像。 |
除了 equalizeHist() 方法外,Imgproc 类还提供了其他方法。它们简要描述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, int ddepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类来增强图像的对比度 −
import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class Main { static int width; static int height; static double alpha = 2; static double beta = 50; public static void main( String[] args ) { try { System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Imgproc.equalizeHist(source, destination); Highgui.imwrite("contrast.jpg", destination); } catch (Exception e) { System.out.println("error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

增强对比度图像

Java DIP - 增强图像亮度
在本章中,我们通过将图像的每个像素与 alpha 值相乘并向其添加另一个 beta 值来增强图像的亮度。
我们 OpenCV 函数 convertTo 自动执行上述操作。它可以在 Mat 包下找到。它的语法如下 −
int alpha = 2; int beta = 50; sourceImage.convertTo(destination, rtype , alpha, beta);
参数说明如下 −
Sr.No. | 参数 &描述 |
---|---|
1 |
destination 它是目标图像。 |
2 |
rtype 它是所需的输出矩阵类型,或者更确切地说是深度,因为通道数与输入相同。如果 rtype 为负数,则输出矩阵将具有与输入相同的类型。 |
3 |
alpha 它是可选的比例因子。 |
4 |
beta 它是添加到缩放值的可选增量。 |
除了 convertTo 方法之外,Mat 类还提供了其他方法。它们被简要描述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
adjustROI(int dtop, int dbottom, int dleft, int dright) 调整子矩阵在父矩阵中的大小和位置。 |
2 |
copyTo(Mat m) 将矩阵复制到另一个矩阵。 |
3 |
diag() 从矩阵中提取对角线,或创建对角线矩阵。 |
4 |
dot(Mat m) 计算两个向量的点积。 |
5 |
reshape(int cn) 改变二维矩阵的形状和/或通道数而不复制数据。 |
6 |
submat(Range rowRange, Range colRange) 提取一个矩形子矩阵。 |
示例
以下示例演示了如何使用 Mat 类来增强图像的亮度 −
import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; public class Main { static int width; static int height; static double alpha = 2; static double beta = 50; public static void main( String[] args ) { try{ System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg",Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows(),source.cols(), source.type()); source.convertTo(destination, -1, alpha, beta); Highgui.imwrite("brightWithAlpha2Beta50.jpg", destination); } catch (Exception e) { System.out.println("error:" + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

增强明亮图像 (Alpha=1 & Beta=50)

增强明亮图像 (Alpha=2 & Beta=50)

Java DIP - 增强图像清晰度
在本章中,我们将学习使用高斯滤波器增加图像的清晰度。
首先我们使用OpenCV 函数 GaussianBlur。它可在 Imgproc 包下找到。其语法如下 −
Imgproc.GaussianBlur(source, destination, new Size(0,0), sigmaX);
参数简要说明 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 源图像。 |
2 |
destination 目标图像。 |
3 |
Size 高斯核大小。 |
4 |
sigmaX X 方向的高斯核标准差方向。 |
此外,我们使用OpenCV函数addWeighted将图像水印应用于图像。它可以在Core包下找到。它的语法如下 −
Core.addWeighted(InputArray src1, alpha, src2, beta, gamma, OutputArray dst);
此函数的参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
src1 它是第一个输入数组。 |
2 |
alpha 它是第一个数组元素的权重。 |
3 |
src2 它是与 src1 大小和通道数相同的第二个输入数组。 |
4 |
Beta 它是第二个数组的权重元素。 |
5 |
gamma 它是添加到每个总和的标量。 |
6 |
dst 它是具有与输入数组相同大小和通道数的输出数组。 |
除了 GaussianBlur 方法之外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 它计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 和 Core 类对图像进行锐化 −
import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.Size; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try{ System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Imgproc.GaussianBlur(source, destination, new Size(0,0), 10); Core.addWeighted(source, 1.5, destination, -0.5, 0, destination); Highgui.imwrite("sharp.jpg", destination); } catch (Exception e) { } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

锐化图像

Java DIP - 图像压缩技术
图像可以通过 Java 轻松压缩和存储。图像压缩涉及将图像转换为 jpg 并存储。
为了压缩图像,我们读取图像并转换为 BufferedImage 对象。
此外,我们从 ImageIO 类中的 getImageWritersByFormatName() 方法获取 ImageWriter。从此 ImageWriter 创建一个 ImageWriteParam 对象。其语法如下所示 −
Iterator<ImageWriter> list = ImageIO.getImageWritersByFormatName("jpg"); ImageWriteParam obj = writer_From_List.getDefaultWriteParam();
从此 ImageWriteParam 对象,您可以通过调用这两个方法设置压缩,即 setCompressionMode() 和 setCompressionQuality()。其语法如下所示 −
obj.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); obj.setCompressionQuality(0.05f);
setCompressionMode() 方法以 Mode_EXPLICIT 为参数。简要描述了其他一些模式 −
Sr.No. | 模式 |
---|---|
1 |
MODE_DEFAULT 它是一个常量值,可以传递到方法中以启用该功能以供将来写入。 |
2 |
MODE_DISABLED 它是一个常量值,可以传递到方法中以禁用该功能以供将来写入。 |
3 |
MODE_EXPLICIT 这是一个常量值,可以传递到方法中以启用该功能以供将来写入。 |
除了压缩方法之外,ImageWriteParam 类还提供了其他方法。它们简要描述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
canOffsetTiles() 如果写入器在写入时可以执行具有非零网格偏移的平铺,则返回 true。 |
2 |
getBitRate(float quality) 返回一个浮点数,表示给定质量级别下输入图像数据的每一位输出数据的位数估计值。 |
3 |
getLocale() 返回当前设置的 Locale,如果只有默认 Locale,则返回 null支持。 |
4 |
isCompressionLossless() 如果当前压缩类型提供无损压缩,则返回 true。 |
5 |
unsetCompression() 它将删除所有先前的压缩类型和质量设置。 |
6 |
unsetTiling() 它将删除通过调用 setTiling 指定的任何先前的图块网格参数。 |
示例
以下示例演示了如何使用 ImageWriteParam 类来压缩图像 −
import java.io.*; import java.util.*; import java.awt.image.*; import javax.imageio.*; import javax.imageio.stream.ImageOutputStream; class Compression { public static void main(String[] args) throws IOException { File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input); File compressedImageFile = new File("compress.jpg"); OutputStream os =new FileOutputStream(compressedImageFile); Iterator<ImageWriter>writers = ImageIO.getImageWritersByFormatName("jpg"); ImageWriter writer = (ImageWriter) writers.next(); ImageOutputStream ios = ImageIO.createImageOutputStream(os); writer.setOutput(ios); ImageWriteParam param = writer.getDefaultWriteParam(); param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionQuality(0.05f); writer.write(null, new IIOImage(image, null, null), param); os.close(); ios.close(); writer.dispose(); } }
输出
执行给定的代码时,它会将图像 digital_image_processing.jpg 压缩为等效的压缩图像,并将其写入硬盘,名称为 compress.jpg。
原始图像

压缩图像 - 质量因数 − 0.05

压缩图像 - 质量因数 − 0.5

Java DIP - 添加边框
在本章中,我们将学习如何为图像添加不同类型的边框。
我们使用 OpenCV 函数 copyMakeBorder。该函数位于 Imgproc 包下。其语法如下所示 −
Imgproc.copyMakeBorder(source,destination,top,bottom,left,right,borderType);
参数说明如下 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 源图像。 |
2 |
destination 目标图像。 |
3 |
top 图像顶部边框的长度(以像素为单位)。 |
4 |
bottom 图像底部边框的长度(以像素为单位)图像。 |
5 |
left 图像左侧边框的长度(以像素为单位)。 |
6 |
right 图像右侧边框的长度(以像素为单位)。 |
7 |
borderType 定义边框的类型。可能的边框有 BORDER_REPLICATE、BORDER_REFLECT、BORDER_WRAP、BORDER_CONSTANT 等。 |
除了 copyMakeBorder() 方法之外,Imgproc 类还提供了其他方法。下面简要介绍一下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类为图像添加边框 −
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class main { public static void main( String[] args ) { try { System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows(),source.cols(),source.type()); int top, bottom, left, right; int borderType; /// Initialize arguments for the filter top = (int) (0.05*source.rows()); bottom = (int) (0.05*source.rows()); left = (int) (0.05*source.cols()); right = (int) (0.05*source.cols()); destination = source; Imgproc.copyMakeBorder(source, destination, top, bottom, left, right, Imgproc.BORDER_WRAP); Highgui.imwrite("borderWrap.jpg", destination); } catch (Exception e) { System.out.println("error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

孤立边框图像

包裹边框图像

反射边框图像

Java DIP - 图像金字塔
图像金字塔只不过是一种显示多分辨率图像的方法。最底层是图像的最高分辨率版本,最顶层是图像的最低分辨率版本。图像金字塔用于处理不同比例的图像。
在本章中,我们对图像进行一些向下采样和向上采样。
我们使用OpenCV函数pyrUp和pyrDown。它们可以在Imgproc包下找到。其语法如下 −
Imgproc.pyrUp(source, destination, destinationSize); Imgproc.pyrDown(source, destination,destinationSize);
参数说明如下 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 源图像。 |
2 |
destination 目标图像。 |
3 |
destinationSize 输出图像的大小。默认情况下,它被计算为 Size((src.cols*2), (src.rows*2))。 |
除了 pyrUp 和 pyrDown 方法之外,Imgproc 类还提供了其他方法。它们被简要描述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类对图像进行上采样和下采样。</p>
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.Size; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class main { public static void main( String[] args ) { try{ System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination1 = new Mat(source.rows()*2, source.cols()*2,source.type()); destination1 = source; Imgproc.pyrUp(source, destination1, new Size(source.cols()*2 source.rows()*2)); Highgui.imwrite("pyrUp.jpg", destination1); source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows()/2,source.cols()/2, source.type()); destination = source; Imgproc.pyrDown(source, destination, new Size(source.cols()/2, source.rows()/2)); Highgui.imwrite("pyrDown.jpg", destination); } catch (Exception e) { System.out.println("error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

在原始图像上,进行pyrUp(上采样)和pyrDown(下采样),采样后的输出如下图所示 −
PyrUP图像
pyrDown图像

Java DIP - 基本阈值处理
阈值处理可以以最简单的方式实现图像分割。图像分割意味着将整个图像分成一组像素,使得每组中的像素具有一些共同的特征。图像分割在定义对象及其边界方面非常有用。
在本章中,我们对图像执行一些基本的阈值处理操作。
我们使用 OpenCV 函数 threshold。它可以在 Imgproc 包下找到。它的语法如下 −
Imgproc.threshold(source, destination, thresh , maxval , type);
参数说明如下 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 源图像。 |
2 |
destination 目标图像。 |
3 |
thresh 阈值。 |
4 |
maxval THRESH_BINARY 使用的最大值和THRESH_BINARY_INV 阈值类型。 |
5 |
type 可能的类型有 THRESH_BINARY、THRESH_BINARY_INV、THRESH_TRUNC 和 THRESH_TOZERO。 |
除了这些阈值方法之外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, int ddepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类对图像执行阈值操作 −
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class main { public static void main( String[] args ) { try{ System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows(),source.cols(),source.type()); destination = source; Imgproc.threshold(source,destination,127,255,Imgproc.THRESH_TOZERO); Highgui.imwrite("ThreshZero.jpg", destination); } catch (Exception e) { System.out.println("error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

在上面的原始图像上,执行了一些阈值操作,如下面的输出所示 −
阈值二元

阈值二元反转

阈值零

Java DIP - 图像形状转换
使用 OpenCV 可以轻松更改图像的形状。图像可以翻转、缩放或沿四个方向旋转。
为了改变图像的形状,我们读取图像并转换为 Mat 对象。其语法如下 −
File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input); //将缓冲图像转换为 Mat。
翻转图像
OpenCV 允许三种类型的翻转代码,如下所述 −
Sr.No. | 翻转代码 &描述 |
---|---|
1 |
0 0 表示,围绕 x 轴翻转。 |
2 |
1 1 表示,围绕 y 轴翻转。 |
3 |
-1 -1 表示,围绕两个轴翻转。 |
我们将适当的翻转代码传递给 Core 类中的方法 flip()。其语法如下所示 −
Core.flip(source mat, destination mat1, flip_code);
方法 flip() 有三个参数 − 源图像矩阵、目标图像矩阵和翻转代码。
除了 flip 方法外,Core 类还提供了其他方法。简要介绍 −
Sr.No. | 方法 &描述 |
---|---|
1 |
add(Mat src1, Mat src2, Mat dst) 计算两个数组或一个数组和一个标量的每个元素的总和。 |
2 |
bitwise_and(Mat src1, Mat src2, Mat dst) 计算两个数组或一个数组和一个标量的每个元素的逐位连接。 |
3 |
bitwise_not(Mat src, Mat dst) 它将数组的每一位反转。 |
4 |
circle(Mat img, Point center, int radius, Scalar color) 它绘制一个圆圈。 |
5 |
sumElems(Mat src) 它使用高斯滤波器模糊图像。 |
6 |
subtract(Mat src1, Scalar src2, Mat dst, Mat mask) 它计算两个数组或数组与标量之间的每个元素差异。 |
示例
以下示例演示了如何使用 Core 类来翻转图像 −
import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.io.File; import javax.imageio.ImageIO; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try { System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input); byte[] data = ((DataBufferByte) image.getRaster(). getDataBuffer()).getData(); Mat mat = new Mat(image.getHeight(),image.getWidth(),CvType.CV_8UC3); mat.put(0, 0, data); Mat mat1 = new Mat(image.getHeight(),image.getWidth(),CvType.CV_8UC3); Core.flip(mat, mat1, -1); byte[] data1 = new byte[mat1.rows()*mat1.cols()*(int)(mat1.elemSize())]; mat1.get(0, 0, data1); BufferedImage image1 = new BufferedImage(mat1.cols(), mat1.rows(), 5); image1.getRaster().setDataElements(0,0,mat1.cols(),mat1.rows(),data1); File ouptut = new File("hsv.jpg"); ImageIO.write(image1, "jpg", ouptut); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
运行上述示例时,它会将名为 digital_image_processing.jpg 的图像翻转为其等效的 HSV 颜色空间图像,并将其写入硬盘上,名称为 flip.jpg。
原始图像

翻转图像

Java DIP - 应用高斯滤波器
在本章中,我们将高斯滤波器应用于模糊图像的图像。我们将使用 OpenCV 函数 GaussianBlur 将高斯滤波器应用于图像。它可以在 Imgproc 包下找到。它的语法如下 −
Imgproc.GaussianBlur(source, destination,Size,SigmaX);
函数参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 源图像。 |
2 |
destination 目标图像。 |
3 |
Size 高斯核大小。 |
4 |
SigmaX X 方向的高斯核标准差方向。 |
除了 GaussianBlur 方法之外,Imgproc 类还提供了其他方法。简要描述它们 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 它计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将高斯滤波器应用于图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.Size; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try { System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Imgproc.GaussianBlur(source, destination,new Size(45,45), 0); Highgui.imwrite("Gaussian45.jpg", destination); } catch (Exception e) { System.out.println("Error:" + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

当此原始图像与大小为 11 和 45 的高斯滤波器进行卷积时,将看到以下输出。
大小为 11 的高斯滤波器

大小为 45 的高斯滤波器

Java DIP - 应用方框过滤器
我们应用模糊图像的方框过滤器。方框过滤器的尺寸可以是 3x3、5x5、9x9 等。
我们使用 OpenCV 函数 filter2D 将方框过滤器应用于图像。它可以在 Imgproc 包下找到。它的语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT);
函数参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
depth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置点 (-1, -1) 默认表示中心。 |
6 |
delta 它是在卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
除了 filter2D() 方法外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 它计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将 Box 过滤器应用于灰度图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 9; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = Mat.ones(kernelSize,kernelSize, CvType.CV_32F); for(int i=0; i<kernel.rows(); i++) { for(int j=0; j<kernel.cols(); j++) { double[] m = kernel.get(i, j); for(int k =0; k<m.length; k++) { m[k] = m[k]/(kernelSize * kernelSize); } kernel.put(i,j, m); } } Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("output.jpg", destination); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

在此示例中,我们将图像与以下过滤器(内核)进行卷积。此过滤器会导致图像随着尺寸的增加而变得模糊。
此原始图像已与大小为 5 的框过滤器进行卷积,如下所示 −
大小为 5 的框过滤器
1/25 | 1/25 | 1/25 | 1/25 | 1/25 |
1/25 | 1/25 | 1/25 | 1/25 | 1/25 |
1/25 | 1/25 | 1/25 | 1/25 | 1/25 |
1/25 | 1/25 | 1/25 | 1/25 | 1/25 |
1/25 | 1/25 | 1/25 | 1/25 |
卷积图像(带有大小为 5 的框式过滤器)

卷积图像(带有大小为 9 的框式过滤器)

Java DIP - 腐蚀和扩张
在本章中,我们学习应用两个非常常见的形态学运算符:扩张和腐蚀。
我们使用OpenCV函数erode和dilate。它们可以在Imgproc包下找到。其语法如下 −
Imgproc.erode(source, destination, element); Imgproc.dilate(source, destination, element);
参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 源图像。 |
2 |
destination 目标图像。 |
3 |
element 用于腐蚀和扩张的结构元素,如果element=Mat(),则使用3 x 3矩形结构元素。 |
除了erode()和dilate()方法外,Imgproc类还提供了其他方法。它们被简要描述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类对图像进行腐蚀和扩张 −
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class main { public static void main( String[] args ) { try{ System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows(),source.cols(),source.type()); destination = source; int erosion_size = 5; int dilation_size = 5; Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2*erosion_size + 1, 2*erosion_size+1)); Imgproc.erode(source, destination, element); Highgui.imwrite("erosion.jpg", destination); source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); destination = source; Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2*dilation_size + 1, 2*dilation_size+1)); Imgproc.dilate(source, destination, element1); Highgui.imwrite("dilation.jpg", destination); } catch (Exception e) { System.out.println("error:" + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

在上面的原始图像上,执行了一些腐蚀和扩张操作,这些操作已在下面的输出中显示 −
腐蚀

扩张

Java DIP - 应用水印
在本章中,我们学习了两种在图像上应用水印的方法。这些方法是 −
- 应用文本水印
- 应用图像水印
应用文本水印
我们使用 OpenCV 函数 putText 将文本水印应用于图像。它可以在 Core 包下找到。它的语法如下 −
Core.putText(source, Text, Point, fontFace ,fontScale , color);
该函数的参数说明如下 −
Sr.No. | 参数 &描述 |
---|---|
1 |
source 它是源图像。 |
2 |
Text 它是将出现在图像上的字符串文本。 |
3 |
Point 它是文本应出现在图像上的点。 |
4 |
fontFace 字体类型。例如 − FONT_HERSHEY_SIMPLEX、FONT_HERSHEY_PLAIN、FONT_HERSHEY_COMPLEX 等。 |
5 |
fontScale 字体比例因子,乘以字体特定的基本大小。 |
6 |
color 文本颜色。 |
除了 putText 方法之外,Core 类还提供了其他方法。它们被简要描述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
normalize(Mat src, Mat dst, double alpha, double beta, int norm_type) 它规范化数组的范数或值范围。 |
2 |
perspectiveTransform(Mat src, Mat dst, Mat m) 它执行向量的透视矩阵变换。 |
3 |
phase(Mat x, Mat y, Mat angle) 它计算 2D 的旋转角度向量。 |
4 |
rectangle(Mat img, Point pt1, Point pt2, Scalar color) 它绘制一个简单、粗或填充的直立矩形。 |
5 |
reduce(Mat src, Mat dst, int dim, int rtype, int dtype) 它将矩阵简化为向量。 |
6 |
transform(Mat src, Mat dst, Mat m) 它对每个数组元素执行矩阵变换。 |
示例
以下示例演示了如何使用 Core 类将文本水印应用于图像 −
import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try{ System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat destination = new Mat(source.rows(),source.cols(), source.type()); Core.putText(source, "Tutorialspoint.com", new Point (source.rows()/2,source.cols()/2), Core.FONT_ITALIC,new Double(1),new Scalar(255)); Highgui.imwrite("watermarked.jpg", source); } catch (Exception e) { System.out.println("Error: "+e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

带文本水印的图像

在图像上应用图像水印
我们将使用 OpenCV 函数 addWeighted 将图像水印应用于图像。它可以在 Core 包下找到。其语法如下 −
Core.addWeighted(InputArray src1, alpha, src2 (Watermark image), beta, gamma, OutputArray dst);
此函数的参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
src1 第一个输入数组。 |
2 |
alpha 第一个数组元素的权重。 |
3 |
src2 第二个输入数组,大小和通道数与 src1 相同。 |
4 |
beta 第二个第二个数组元素。 |
5 |
gamma 它是添加到每个总和的标量。 |
6 |
dst 它是具有与输入数组相同大小和通道数的输出数组。 |
示例
以下示例演示了如何使用 Core 类将图像水印应用于图像 −
import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try{ System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("digital_image_processing.jpg", Highgui.CV_LOAD_IMAGE_COLOR); Mat waterMark = Highgui.imread("watermark.png", Highgui.CV_LOAD_IMAGE_COLOR); Rect ROI = new Rect(waterMark.rows() * 4,waterMark.cols(), waterMark.cols(),waterMark.rows()); Core.addWeighted(source.submat(ROI), 0.8, waterMark, 0.2, 1, source.submat(ROI)); Highgui.imwrite("watermarkedImage.jpg", source); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

水印图像

带水印的图像

Java DIP - 理解卷积
卷积是对两个函数 f 和 g 的数学运算。在这种情况下,函数 f 和 g 是图像,因为图像也是二维函数。
执行卷积
为了对图像执行卷积,请采取以下步骤 −
- 仅翻转蒙版(水平和垂直)一次。
- 将蒙版滑到图像上。
- 将相应元素相乘,然后将它们相加。
- 重复此过程,直到计算出图像的所有值。
我们使用 OpenCV 函数 filter2D 将卷积应用于图像。它可以在 Imgproc 包下找到。其语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT );
函数参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
depth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置点 (-1, -1) 默认表示中心。 |
6 |
delta 它是在卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
示例
以下示例演示了如何使用 Imgproc 类对灰度图像进行卷积。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 3; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) { { put(0,0,0); put(0,1,0); put(0,2,0); put(1,0,0); put(1,1,1); put(1,2,0); put(2,0,0); put(2,1,0); put(2,2,0); } }; Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("original.jpg", destination); } catch (Exception e) { System.out.println("Error:" + e.getMessage()); } } }
输出
在此示例中,我们将图像与以下过滤器(内核)进行卷积。此过滤器会生成原始图像,因为它是 −
0 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
原始图像

卷积图像

Java DIP - Prewitt 算子
Prewitt 算子用于图像中的边缘检测。它检测两种类型的边缘:垂直边缘和水平边缘。
我们使用 OpenCV 函数 filter2D 将 Prewitt 算子应用于图像。它可以在 Imgproc 包下找到。它的语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT);
函数参数如下 −
Sr.No. | 参数 &描述 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
depth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置点 (-1, -1) 默认表示中心。 |
6 |
delta 它是在卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
除了 filter2D 方法外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 它计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将 Prewitt 运算符应用于灰度图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 9; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) { { put(0,0,-1); put(0,1,0); put(0,2,1); put(1,0-1); put(1,1,0); put(1,2,1); put(2,0,-1); put(2,1,0); put(2,2,1); } }; Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("output.jpg", destination); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

此原始图像与垂直边缘的 Prewitt 算子进行卷积,如下所示 −
垂直方向
-1 | 0 | 1 |
-1 | 0 | 1 |
-1 | 0 | 1 |
卷积图像(垂直方向)

此原始图像还与水平边缘的 Prewitt 算子进行了卷积,如下所示 −
水平方向
-1 | -1 | -1 |
0 | 0 | 0 |
1 | 1 | 1 |
卷积图像(水平方向)

Java DIP - Sobel 算子
Sobel 算子与 Prewitt 算子非常相似。它也是一个导数掩码,用于边缘检测。Sobel 算子用于检测图像中的两种边缘:垂直方向边缘和水平方向边缘。
我们将使用 OpenCV 函数 filter2D 将 Sobel 算子应用于图像。它可以在 Imgproc 包下找到。它的语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT);
函数参数如下 −
Sr.No. | 参数 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
depth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置点 (-1, -1) 默认表示中心。 |
6 |
delta 它是在卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
除了 filter2D 方法外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将 Sobel 算子应用于灰度图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 9; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) { { put(0,0,-1); put(0,1,0); put(0,2,1); put(1,0-2); put(1,1,0); put(1,2,2); put(2,0,-1); put(2,1,0); put(2,2,1); } }; Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("output.jpg", destination); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

此原始图像与垂直边缘的 Sobel 算子进行卷积,如下所示 −
垂直方向
-1 | 0 | 1 |
-2 | 0 | 2 |
-1 | 0 | 1 |
卷积图像(垂直方向)

此原始图像与水平边缘的 Sobel 算子进行卷积,如下所示 −
水平方向
-1 | -2 | -1 |
0 | 0 | 0 |
1 | 2 | 1 |
卷积图像(水平方向)

Java DIP - Kirsch 运算符
Kirsch 罗盘掩模是另一种用于边缘检测的衍生掩模。此运算符也称为方向掩模。在此运算符中,我们取一个掩模并将其沿所有八个罗盘方向旋转以获取八个方向的边缘。
我们将使用 OpenCV 函数 filter2D 将 Kirsch 运算符应用于图像。它可以在 Imgproc 包下找到。其语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT );
函数参数如下 −
Sr.No. | 参数 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
depth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置点 (-1, -1) 默认表示中心。 |
6 |
delta 它是在卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
除了 filter2D() 方法外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将 Kirsch 算子应用于灰度图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 9; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) { { put(0,0,-3); put(0,1,-3); put(0,2,-3); put(1,0-3); put(1,1,0); put(1,2,-3); put(2,0,5); put(2,1,5); put(2,2,5); } }; Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("output.jpg", destination); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

此原始图像与东边的 Kirsch 算子进行卷积,如下所示 −
Kirsch East
-3 | -3 | -3 |
-3 | 0 | -3 |
5 | 5 | 5 |
卷积图像(Kirsch East)

此原始图像与西南边缘的 Kirsch 运算符卷积,如下所示 −
Kirsch South West
5 | 5 | -3 |
5 | 0 | -3 |
-3 | -3 | -3 |
卷积图像 (Kirsch South West)

Java DIP - Robinson 罗宾逊算子
Robinson 罗宾逊罗盘掩模是另一种用于边缘检测的衍生掩模。此算子也称为方向掩模。在此算子中,我们取一个掩模并将其沿所有八个主要方向旋转以获取八个方向的边缘。
我们将使用 OpenCV 函数 filter2D 将罗宾逊算子应用于图像。它可以在 Imgproc 包下找到。其语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT );
函数参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
depth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置 Point(-1, -1) 默认表示中心。 |
6 |
delta 它是卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
除了 filter2D 方法之外,Imgproc 类还提供了其他方法。简要描述它们 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将 Robinson 算子应用于灰度图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 9; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) { { put(0,0,-1); put(0,1,0); put(0,2,1); put(1,0-2); put(1,1,0); put(1,2,2); put(2,0,-1); put(2,1,0); put(2,2,1); } }; Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("output.jpg", destination); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

此原始图像与北边的罗宾逊算子进行卷积,如下所示 −
北方向蒙版
-1 | 0 | 1 |
-2 | 0 | 2 |
-1 | 0 | 1 |
卷积图像(Robinson North)

此原始图像也已与东边的 Robinson 算子进行卷积,如下所示 −
东方向蒙版
-1 | -2 | -1 |
0 | 0 | 0 |
1 | 2 | 1 |
卷积图像(Robinson East)

Java DIP - Laplacian 拉普拉斯算子
拉普拉斯算子也是一个导数算子,用于查找图像中的边缘。拉普拉斯算子与 Prewitt、Sobel、Robinson 和 Kirsch 等其他算子的主要区别在于,这些都是一阶导数掩码,而拉普拉斯算子是二阶导数掩码。
我们使用 OpenCV 函数 filter2D 将拉普拉斯算子应用于图像。它可以在 Imgproc 包下找到。它的语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT );
函数参数如下 −
Sr.No. | 参数 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
depth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置点 (-1, -1) 默认表示中心。 |
6 |
delta 它是在卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
除了 filter2D() 方法外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将拉普拉斯算子应用于灰度图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 9; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F) { { put(0,0,0); put(0,1,-1) put(0,2,0); put(1,0-1); put(1,1,4); put(1,2,-1); put(2,0,0); put(2,1,-1); put(2,2,0); } }; Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("output.jpg", destination); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

此原始图像与拉普拉斯负算子进行卷积,如下所示 −
拉普拉斯负算子
0 | -1 | 0 |
-1 | 4 | -1 |
0 | -1 | 0 |
卷积图像(拉普拉斯负值)

此原始图像与拉普拉斯正算子卷积,如下所示 −
拉普拉斯正值
0 | 1 | 0 |
1 | -4 | 1 |
0 | 1 | 0 |
卷积图像(拉普拉斯正值)

Java DIP - 加权平均滤波器
在加权平均滤波器中,我们赋予中心值更多权重,因此中心的贡献大于其余值。由于加权平均滤波,我们可以控制图像的模糊。
我们使用 OpenCV 函数 filter2D 将加权平均滤波器应用于图像。它可以在 Imgproc 包下找到。其语法如下 −
filter2D(src, dst,depth, kernel, anchor, delta, BORDER_DEFAULT );
函数参数如下所述 −
Sr.No. | 参数 &描述 |
---|---|
1 |
src 源图像。 |
2 |
dst 目标图像。 |
3 |
ddepth dst的深度。负值(例如 -1)表示深度与源相同。 |
4 |
kernel 它是要扫描图像的内核。 |
5 |
anchor 它是锚点相对于其内核的位置。位置 Point(-1, -1) 默认表示中心。 |
6 |
delta 它是卷积期间要添加到每个像素的值。默认情况下为 0。 |
7 |
BORDER_DEFAULT 我们默认使用此值。 |
除了 filter2D() 方法外,Imgproc 类还提供了其他方法。它们简要描述如下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将加权平均滤波器应用于灰度图像。
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class convolution { public static void main( String[] args ) { try { int kernelSize = 9; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows(),source.cols(),source.type()); Mat kernel = Mat.ones(kernelSize,kernelSize, CvType.CV_32F) { for(int i=0; i<kernel.rows(); i++) { for(int j=0; j<kernel.cols(); j++) { double[] m = kernel.get(i, j); for(int k =0; k<m.length; k++) { if(i==1 && j==1) { m[k] = 10/18; } else{ m[k] = m[k]/(18); } } kernel.put(i,j, m); } } }; Imgproc.filter2D(source, destination, -1, kernel); Highgui.imwrite("output.jpg", destination); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

此原始图像与下面给出的加权平均滤波器进行卷积 −
加权平均滤波器
1 | 1 | 1 |
1 | 10 | 1 |
1 | 1 | 1 |
卷积图像

Java DIP - 创建缩放效果
缩放是放大图像的过程,以便图像中的细节变得更加清晰和突出。
我们使用OpenCV函数resize对图像进行缩放。它可以在Imgproc包下找到。它的语法如下 −
Imgproc.resize(source,destination, destination.size(),zoomFactor,zoomFactor,Interpolation);
在调整大小函数中,我们传递源图像、目标图像及其大小、缩放系数以及要使用的插值方法。
可用的插值方法如下 −
Sr.No. | 插值方法 &描述 |
---|---|
1 |
INTER_NEAREST 它是最近邻插值。 |
2 |
INTER_LINEAR 它是双线性插值(默认使用)。 |
3 |
INTER_AREA 它是使用像素面积关系进行重采样。它可能是图像抽取的首选方法,因为它可以提供更自由的结果。 |
4 |
INTER_CUBIC 它是 4x4 像素邻域上的双三次插值。 |
5 |
INTER_LANCZOS4 它是 8x8 像素邻域上的 Lanczos 插值。 |
除了调整大小方法之外,Imgproc 类还提供了其他方法。它们被简要描述 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, int ddepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 它计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类对图像进行缩放。
import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try { int zoomingFactor = 2; System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); Mat source = Highgui.imread("image.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat destination = new Mat(source.rows() * zoomingFactor, source.cols()* zoomingFactor,source.type()); Imgproc.resize(source, destination, destination.size(), zoomingFactor,zoomingFactor,Imgproc.INTER_NEAREST); Highgui.imwrite("zoomed.jpg", destination); } catch (Exception e) { System.out.println("Error: "+e.getMessage()); } } }
输出
执行给定的代码时,将看到以下输出 −
原始图像

缩放图像(缩放系数 − 2)
Java DIP - 开源库
在本章中,我们将探讨一些广泛使用且可以轻松集成到项目中的免费图像处理库。这些库包括 −
- ImageJ
- Fiji
- Commons Imaging
- ImageMagick
- Endrov
- LeadTools
- OpenCv
ImageJ
ImageJ 是一个受 NIH Image for the Macintosh 启发的公共领域 Java 图像处理程序。它可以显示、编辑、分析、处理、保存和打印 8 位、16 位和 32 位图像。
下面介绍了 ImageJ 的一些基本功能 −
Sr.No. | 功能 &描述 |
---|---|
1 |
随处运行 ImageJ 用 Java 编写,可以在 Linux、Mac OS X 和 Windows 上以 32 位和 64 位模式运行。 |
2 |
开源 ImageJ 及其 Java 源代码可免费获取,并且属于公共领域。 |
3 |
工具包 使用 ImageJ 作为图像处理工具包(类库)来开发小程序、servlet 或应用程序。 |
4 |
数据类型 8 位灰度或索引颜色、16 位无符号整数、32 位浮点和 RGB 颜色。 |
5 |
文件格式 打开和保存 GIF、JPEG、BMP、PNG、PGM、FITS 和 ASCII。打开 DICOM。使用 URL 打开 TIFF、GIF、JPEG、DICOM 和原始数据。 |
6 |
选择 创建矩形、椭圆形或不规则区域选择。创建线和点选择。 |
7 |
图像增强 支持对 8 位灰度和 RGB 彩色图像进行平滑、锐化、边缘检测、中值滤波和阈值处理。 |
8 |
颜色处理 将 32 位彩色图像拆分为 RGB 或 HSV 分量。将 8 位分量合并为彩色图像。 |
Fiji
Fiji 是一个图像处理包。它可以被描述为 ImageJ(和 ImageJ2)的发行版,以及 Java、Java3D 和大量插件,组织成一个连贯的菜单结构。Fiji 与 ImageJ 的比较就像 Ubuntu 与 Linux 的比较一样。
除了 ImageJ 的基本功能外,Fiji 的一些高级功能如下所述 −
Sr.No. | 功能和说明 |
---|---|
1 |
注册 3D 图像 这涉及弹性对齐和蒙太奇、特征提取、图像稳定器等。 |
2 |
分割图像 它提供超过 35 种分割类型。 |
3 |
有用的键盘快捷键 Fuji 有很多键盘快捷键。 |
4 |
脚本 允许使用宏、JavaScript、JRuby 编写脚本, Jython、Clojure 和 Beanshell。 |
5 |
开发插件 使用脚本编辑器开始开发插件,然后运行插件。 |
6 |
ImageJ 技巧 ImageJ 易于使用,但有时您希望实际实现某些功能,但不知道如何触发。 |
Commons Imaging
Apache Commons Imaging,以前称为 Apache Commons Sanselan,是一个读取和写入各种图像格式的库,包括快速解析图像信息如(大小、颜色、空间、ICC 配置文件等)和元数据。
下面描述了 ImageJ 的一些基本功能 −
Sr.No. | 功能与说明 |
---|---|
1 |
Java Apache Commons Imaging 是用 100% 纯 Java 编写的。它可以在任何 JVM 和任何平台上执行,无需修改。 |
2 |
图像格式 它可以读取和写入各种图像格式,并支持所有或大多数其他库所遗漏的一些变体和编码。 |
3 |
元数据支持 它支持以结构化方式读取和写入各种元数据,包括 EXIF 元数据。 |
4 |
网络友好 它是网络友好的。 Commons Imaging 仅读取所需的数据,并缓存读取的数据,以免对网络造成太大负担。 |
5 |
易于使用 它的设计非常易于使用。它有一个简单、干净的界面。大多数操作都是一个单一的 Imaging 方法调用。 |
6 |
透明 Commons Imaging 旨在实现透明。没有隐藏的缓冲区需要处理,没有本机内存需要释放,没有后台线程。 |
7 |
开源 它是免费软件/开源。它可在 Apache 软件许可下使用。 |
8 |
颜色转换 ColorConversions 类提供在以下颜色空间之间转换的方法 − CIE-L*CH、CIE-L*ab、CIE-L*uv、CMY、CMYK、HSL、HSV、Hunter-Lab、RGB、XYZ 和 YXY。 |
ImageMagick
ImageMagick 是一款用于创建、编辑、合成或转换位图图像的软件套件。它可以读取和写入 100 多种格式的图像,包括 DPX、EXR、GIF、JPEG、JPEG-2000、PDF、PNG、Postscript、SVG 和 TIFF。使用 ImageMagick 可以调整图像大小、翻转、镜像、旋转、扭曲、剪切和变换图像,调整图像颜色,应用各种特殊效果,或绘制文本、线条、多边形、椭圆和贝塞尔曲线。
ImageMagick 的一些基本功能如下所述 −
Sr.No. | 功能 &描述 |
---|---|
1 |
格式转换 它将图像从一种格式转换为另一种格式(例如 PNG 到 JPEG)。 |
2 |
变换 它可以调整图像的大小、旋转、裁剪、翻转或修剪图像。 |
3 |
透明度 它使图像的某些部分不可见。 |
4 |
绘制 它向图像添加形状或文本。 |
5 |
装饰 它向图像添加边框或框架。 |
6 |
特殊效果 它可以模糊、锐化、阈值或为图像着色。 |
7 |
动画 它可以从一组图像。 |
8 |
合成 它可以将一张图像重叠在另一张图像上。 |
9 |
形状形态 它提取特征,描述形状并识别图像中的模式。 |
10 |
加密或解密图像 它将普通图像转换为难以理解的胡言乱语并转回再次。 |
Endrov
Endrov 是一个多用途图像分析程序。它是独立编写的,旨在解决其他免费软件和许多商业软件包的许多缺点。
Endrov 的一些基本功能如下所述 −
Sr.No. | 功能和说明 |
---|---|
1 |
查看数据 它以 2D 和 3D 形式查看数据。设计用于处理复杂的 4D 数据方案和无限数量的通道,其中每个通道可以有自己的 X、Y 和 Z 分辨率。 |
2 |
注释您的图像 它可以自动或手动注释您的图像,以了解它们并获取统计数据。 |
3 |
撤消和重做 它可以撤消和重做所有操作。 |
4 |
惰性求值 它从一开始就设计用于处理大型图像集。 Endrov 使用惰性求值,这是研究编程语言中最常见的概念。 |
5 |
脚本语言 它支持图形脚本语言以及传统脚本。 |
6 |
Java 用 Java 编写。插件架构允许使用新的 Java 插件轻松扩展。它可以与 Matlab 交互。 |
7 |
格式 它使用 Bio 格式访问几乎所有商业和开放文件格式。 |
8 |
微观处理 它可以用一个程序控制所有显微镜并进行即时图像分析。 |
LEADTOOLS
LEADTOOLS 提供超过 200 种图像处理功能,包括文档清理、医学图像增强、色彩转换和校正、降噪、边缘检测等。
下面介绍了 LEADTOOLS 的一些基本功能 −
Sr.No. | 功能 &描述 |
---|---|
1 |
扫描文档图像处理 这组强大的函数可以读取扫描文档中的瑕疵和缺陷,例如打孔、倾斜角度、边框、灰尘斑点等。 |
2 |
医学图像处理 通过移动、选择、减去和移除背景来增强图像或突出显示细节,以获得更好的视觉效果。 |
3 |
几何变换 这些函数可用于清理、对齐、校正图像或应用艺术 3D 效果。 |
4 |
亮度和对比度 这些函数可用于增强图像、应用艺术效果或帮助诊断评估医学图像。 |
5 |
色彩空间转换 它们可以为单线程和多线程应用程序(包括 IIS 和 Windows WF 托管应用程序)添加图像色彩空间功能。 |
6 |
色彩校正 这些函数用于校正交换色彩通道的图像、平衡色彩强度或执行各种图像分析任务。 |
7 |
图像增强 这些函数用于纠正摄影中的常见错误,例如红眼和色彩不平衡,以及帮助诊断评估医学图像。 |
8 |
感兴趣区域 这些函数用于创建和修改图像中的感兴趣区域,以对图像的特定部分执行图像处理功能,节省条形码和 OCR 识别时间或执行各种图像分析任务。 |
OpenCV
OpenCV 是在 BSD 许可下发布的,因此它可免费用于学术和商业用途。它具有 C++、C、Python 和 Java 接口,支持 Windows、Linux、Mac OS、iOS 和 Android。OpenCV 专为提高计算效率而设计,重点关注实时应用。该库以优化的 C/C++ 编写,可充分利用多核处理。
简要介绍了 OpenCV 的一些基本功能 −
Sr.No. | 特征与描述 |
---|---|
1 |
平滑图像 这涉及应用模糊、高斯模糊、中值模糊和双边滤波器。 |
2 |
侵蚀和扩张 它可以应用两个非常常见的形态学运算符 −膨胀和腐蚀。 |
3 |
形态学变换 OpenCV 函数 morphologyEx 可应用形态学变换,如开、闭、TopHat 和 BlackHat 等。 |
4 |
图像金字塔 OpenCV 函数 pyrUp 和 pyrDown 可对给定图像进行向下采样或向上采样。 |
4 |
基本阈值操作 使用 OpenCV 函数执行基本阈值操作阈值。 |
5 |
为图像添加边框 OpenCV 函数 copyMakeBorder 用于设置边框(图像的额外填充)。 |
7 |
重新映射 在 OpenCV 中,函数 remap 提供了一个简单的重新映射实现。 |
8 |
直方图计算 出于简单目的,OpenCV 实现了函数 calcHist,该函数计算一组数组(通常是图像或图像平面)的直方图。它最多可以操作 32 个维度。 |
Java DIP - OpenCV 简介
OpenCV 是在 BSD 许可下发布的,因此它可免费用于学术和商业用途。它具有 C++、C、Python 和 Java 接口,并支持 Windows、Linux、Mac OS、iOS 和 Android。
OpenCV 专为提高计算效率而设计,重点关注实时应用程序。该库以优化的 C/C++ 编写,可利用多核处理。
下面介绍了 OpenCV 的一些基本功能 −
Sr.No. | 功能 &描述 |
---|---|
1 |
平滑图像 这涉及应用模糊、高斯模糊、中值模糊和双边滤波器。 |
2 |
侵蚀和扩张 它可以应用两个非常常见的形态学运算符 −膨胀和腐蚀。 |
3 |
形态学变换 OpenCV 函数 morphologyEx 可应用形态学变换,如开、闭、TopHat 和 BlackHat 等。 |
4 |
图像金字塔 OpenCV 函数 pyrUp 和 pyrDown 可对给定图像进行向下采样或向上采样。 |
4 |
基本阈值操作 它可以使用 OpenCV 函数执行基本阈值操作阈值。 |
5 |
为图像添加边框 OpenCV 函数 copyMakeBorder 用于设置边框(图像的额外填充)。 |
7 |
重新映射 在 OpenCV 中,函数 remap 提供了一个简单的重新映射实现。 |
8 |
直方图计算 出于简单目的,OpenCV 实现了函数 calcHist,该函数计算一组数组(通常是图像或图像平面)的直方图。它最多可以处理 32 个维度。 |
集成 OpenCV
以下步骤说明如何将 OpenCV 集成到您的应用程序中。
下载 OpenCV
您可以从其官方网站此处下载 OpenCV。
创建用户库
此外,我们创建 OpenCV 的用户库,以便将其用作未来的项目。
启动 Eclipse
从菜单中选择窗口 -> 首选项。
在 Java -> 构建路径 -> 用户库下导航并单击新建。
现在输入库的名称。例如,OpenCV-2.4.6。
之后,选择您的新用户库(即 OpenCV-2.4.6)并单击添加外部 JAR。
浏览 C:\OpenCV-2.4.6\build\java\ 并选择 opencv-246.jar。添加 jar 后,扩展 opencv-246.jar 并选择本机库位置,然后按编辑。
选择外部文件夹...并浏览以选择文件夹 C:\OpenCV-2.4.6\build\java\x64。如果您使用的是 32 位系统,则需要选择 x86 文件夹而不是 x64。
按"确定"即可完成。
现在您的用户库已创建。现在您可以在任何项目中重复使用此配置。
创建 OpenCV 项目
在 eclipse 中创建一个新的 java 项目。
在"Java 设置"步骤的"库"选项卡下,选择"添加库...",然后选择"OpenCV-2.4.6",然后单击"完成"。
单击"完成",即可完成。
Java DIP - OpenCV 灰度转换
为了使用 OpenCV 将彩色图像转换为灰度图像,我们将图像读入 BufferedImage 并将其转换为 Mat 对象。其语法如下 −
File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input); //将缓冲图像转换为 Mat。
然后,您可以使用 Imgproc 类中的方法 cvtColor() 将图像从 RGB 转换为灰度格式。其语法如下 −
Imgproc.cvtColor(source mat, destination mat1, Imgproc.COLOR_RGB2GRAY);
方法 cvtColor() 需要三个参数,分别是源图像矩阵、目标图像矩阵和颜色转换类型。
除了 cvtColor 方法之外,Imgproc 类还提供了其他方法。它们列在下面 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, intdepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 它计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将图像转换为灰度 −
import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.io.File; import javax.imageio.ImageIO; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try { System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input); byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3); mat.put(0, 0, data); Mat mat1 = new Mat(image.getHeight(),image.getWidth(),CvType.CV_8UC1); Imgproc.cvtColor(mat, mat1, Imgproc.COLOR_RGB2GRAY); byte[] data1 = new byte[mat1.rows() * mat1.cols() * (int)(mat1.elemSize())]; mat1.get(0, 0, data1); BufferedImage image1 = new BufferedImage(mat1.cols(),mat1.rows(), BufferedImage.TYPE_BYTE_GRAY); image1.getRaster().setDataElements(0, 0, mat1.cols(), mat1.rows(), data1); File ouptut = new File("grayscale.jpg"); ImageIO.write(image1, "jpg", ouptut); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定示例时,它会将图像名称 digital_image_processing.jpg 转换为其等效的灰度图像,并将其写入硬盘上,名称为 grayscale.jpg。
原始图像

灰度图像

Java DIP - OpenCV 颜色空间转换
为了使用 OpenCV 将一个图像的颜色空间更改为另一个,我们将图像读入 BufferedImage 并将其转换为 Mat 对象。其语法如下所示 −
File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input); //将 Buffered Image 转换为 Mat。
OpenCv 允许多种颜色转换类型,所有这些类型都可以在 Imgproc 类中找到。一些类型简要描述 −
Sr.No. | 颜色转换类型 |
---|---|
1 | COLOR_RGB2BGR |
2 | COLOR_RGB2BGRA |
3 | COLOR_RGB2GRAY |
4 | COLOR_RGB2HLS |
5 | COLOR_RGB2HSV |
6 | COLOR_RGB2Luv |
7 | COLOR_RGB2YUV |
8 | COLOR_RGB2Lab |
从任何颜色转换类型中,只需将适当的一个传递到 Imgproc 类中的方法 cvtColor() 中。其语法如下所示 −
Imgproc.cvtColor(source mat, destination mat1, Color_Conversion_Code);
方法 cvtColor() 需要三个参数,分别是源图像矩阵、目标图像矩阵和颜色转换类型。
除了 cvtColor() 方法之外,Imgproc 类还提供了其他方法。下面简要介绍一下 −
Sr.No. | 方法 &描述 |
---|---|
1 |
cvtColor(Mat src, Mat dst, int code, int dstCn) 它将图像从一个颜色空间转换为另一个颜色空间。 |
2 |
dilate(Mat src, Mat dst, Mat kernel) 它使用特定的结构元素来扩大图像。 |
3 |
equalizeHist(Mat src, Mat dst) 它均衡直方图灰度图像。 |
4 |
filter2D(Mat src, Mat dst, int ddepth, Mat kernel, Point anchor, double delta) 它将图像与内核进行卷积。 |
5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯滤波器模糊图像。 |
6 |
integral(Mat src, Mat sum) 它计算图像的积分。 |
示例
以下示例演示了如何使用 Imgproc 类将图像从一个颜色空间转换为另一个颜色空间。
import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.io.File; import javax.imageio.ImageIO; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.imgproc.Imgproc; public class Main { public static void main( String[] args ) { try { System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); File input = new File("digital_image_processing.jpg"); BufferedImage image = ImageIO.read(input); byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); Mat mat = new Mat(image.getHeight(),image.getWidth(), CvType.CV_8UC3); mat.put(0, 0, data); Mat mat1 = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3); Imgproc.cvtColor(mat, mat1, Imgproc.COLOR_RGB2HSV); byte[] data1 = new byte[mat1.rows()*mat1.cols()*(int)(mat1.elemSize())]; mat1.get(0, 0, data1); BufferedImage image1 = new BufferedImage(mat1.cols(), mat1.rows(), 5); image1.getRaster().setDataElements(0, 0, mat1.cols(), mat1.rows(), data1); File ouptut = new File("hsv.jpg"); ImageIO.write(image1, "jpg", ouptut); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } }
输出
执行给定示例时,它会将图像名称 digital_image_processing.jpg 转换为其等效的 HSV 颜色空间图像,并将其写入硬盘上,名称为 hsv.jpg。
原始图像 (RGB)

转换后的图像 (HSV)
