- Java 數字影像處理
- DIP - 首頁
- DIP - 簡介
- DIP - Java BufferedImage 類
- DIP - 影像下載與上傳
- DIP - 影像畫素
- DIP - 灰度轉換
- DIP - 增強影像對比度
- DIP - 增強影像亮度
- DIP - 增強影像銳度
- DIP - 影像壓縮技術
- DIP - 新增影像邊框
- DIP - 影像金字塔
- DIP - 基本閾值化
- DIP - 影像形狀轉換
- DIP - 高斯濾波器
- DIP - 盒式濾波器
- DIP - 腐蝕與膨脹
- DIP - 水印
- DIP - 理解卷積
- DIP - Prewitt運算元
- DIP - Sobel運算元
- DIP - Kirsch運算元
- DIP - Robinson運算元
- DIP - Laplacian運算元
- DIP - 加權平均濾波器
- DIP - 建立縮放效果
- DIP - 開源庫
- DIP - OpenCV 簡介
- DIP - OpenCV 灰度轉換
- DIP - 色彩空間轉換
- DIP 有用資源
- DIP - 快速指南
- DIP - 有用資源
- DIP - 討論
Java 數字影像處理 - 快速指南
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)
| 序號 | 方法及描述 |
|---|---|
| 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 物件在螢幕上繪製一些文字:
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 = "https://tutorialspoint.tw"; URL url = new URL(website);
除了上述方法外,URL 類中還提供了其他方法,簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 = "https://tutorialspoint.tw/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 類中還提供了其他方法,簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 將影像上傳到伺服器:
客戶端程式碼
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 類還支援其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 類中還提供了其他方法,簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 1 |
brighter() 它建立一個新的 Color,它是此 Color 的更亮版本。 |
| 2 |
darker() 它建立一個新的 Color,它是此 Color 的更暗版本。 |
| 3 |
getAlpha() 它返回 0-255 範圍內的 alpha 分量。 |
| 4 |
getHSBColor(float h, float s, float b) 它根據 HSB 顏色模型的指定值建立一個 Color 物件。 |
| 5 |
HSBtoRGB(float hue, float saturation, float brightness) 它將 HSB 模型指定的顏色的分量轉換為預設 RGB 模型的等效值集。 |
| 6 |
toString() 它返回此 Color 的字串表示形式。 |
最後一步是將這三個值全部加起來,並將其重新設定為相應的畫素值。其語法如下:
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);
引數描述如下:
| 序號 | 引數及描述 |
|---|---|
| 1 |
源 它是 8 位單通道源影像。 |
| 2 |
目標 它是目標影像。 |
除了 equalizeHist() 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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);
引數描述如下:
| 序號 | 引數及描述 |
|---|---|
| 1 |
目標影像 它是目標影像。 |
| 2 |
輸出資料型別 它是所需的輸出矩陣型別,或者更確切地說是深度,因為通道數與輸入相同。如果 rtype 為負,則輸出矩陣將與輸入具有相同的型別。 |
| 3 |
alpha 它是可選的縮放因子。 |
| 4 |
beta 它是新增到縮放值中的可選增量。 |
除了 convertTo 方法外,Mat 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 1 |
adjustROI(int dtop, int dbottom, int dleft, int dright) 它調整子矩陣在父矩陣中的大小和位置。 |
| 2 |
copyTo(Mat m) 它將矩陣複製到另一個矩陣。 |
| 3 |
diag() 它從矩陣中提取對角線,或建立一個對角矩陣。 |
| 4 |
dot(Mat m) 它計算兩個向量的點積。 |
| 5 |
reshape(int cn) 它更改 2D 矩陣的形狀和/或通道數,而無需複製資料。 |
| 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 數字影像處理 - 增強影像銳度
本章中,我們將學習如何使用高斯濾波器來提高影像的銳度。
首先,我們使用OpenCV函式GaussianBlur。它可以在Imgproc包中找到。其語法如下所示:
Imgproc.GaussianBlur(source, destination, new Size(0,0), sigmaX);
引數如下所示:
| 序號 | 引數及描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
目標影像 它是目標影像。 |
| 3 |
尺寸 它是高斯核的大小。 |
| 4 |
sigmaX 它是高斯核在 X 方向上的標準差。 |
此外,我們使用OpenCV函式addWeighted將影像水印應用於影像。它可以在Core包中找到。其語法如下所示:
Core.addWeighted(InputArray src1, alpha, src2, beta, gamma, OutputArray dst);
該函式的引數如下所示:
| 序號 | 引數及描述 |
|---|---|
| 1 |
src1 它是第一個輸入陣列。 |
| 2 |
alpha 它是第一個陣列元素的權重。 |
| 3 |
src2 它是第二個輸入陣列,其大小和通道數與 src1 相同。 |
| 4 |
Beta 它是第二個陣列元素的權重。 |
| 5 |
gamma 它是新增到每個和中的標量。 |
| 6 |
dst 它是輸出陣列,其大小和通道數與輸入陣列相同。 |
除了 GaussianBlur 方法外,Imgproc 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - 影像壓縮技術
影像可以透過 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 作為引數。下面簡要介紹其他一些模式:
| 序號 | 模式 |
|---|---|
| 1 |
MODE_DEFAULT 它是一個常數值,可以傳遞給方法以啟用該功能以供將來寫入。 |
| 2 |
MODE_DISABLED 它是一個常數值,可以傳遞給方法以停用該功能以供將來寫入。 |
| 3 |
MODE_EXPLICIT 它是一個常數值,可以傳遞給方法以啟用該功能以供將來寫入。 |
除了壓縮方法外,ImageWriteParam 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 1 |
canOffsetTiles() 如果寫入器可以在寫入時執行具有非零網格偏移量的平鋪,則返回 true。 |
| 2 |
getBitRate(float quality) 它返回一個浮點數,表示在給定質量級別下每個輸入影像資料位輸出資料位的估計數。 |
| 3 |
getLocale() 它返回當前設定的區域設定,如果僅支援預設區域設定,則返回 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 數字影像處理 - 新增邊框
本章中,我們將學習如何向影像新增不同型別的邊框。
我們使用OpenCV函式copyMakeBorder。它可以在Imgproc包中找到。其語法如下所示:
Imgproc.copyMakeBorder(source,destination,top,bottom,left,right,borderType);
引數描述如下:
| 序號 | 引數及描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
目標影像 它是目標影像。 |
| 3 |
頂部 它是影像頂部邊框的畫素長度。 |
| 4 |
底部 它是影像底部邊框的畫素長度。 |
| 5 |
左邊 它是影像左邊邊框的畫素長度。 |
| 6 |
右邊 它是影像右邊邊框的畫素長度。 |
| 7 |
邊框型別 它定義邊框的型別。可能的邊框有 BORDER_REPLICATE、BORDER_REFLECT、BORDER_WRAP、BORDER_CONSTANT 等。 |
除了 copyMakeBorder() 方法外,Imgproc 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - 影像金字塔
影像金字塔不過是一種顯示多解析度影像的方法。最下面一層是影像的最高解析度版本,最上面一層是影像的最低解析度版本。影像金字塔用於處理不同尺度的影像。
本章中,我們將對影像進行一些下采樣和上取樣操作。
我們使用OpenCV函式pyrUp和pyrDown。它們可以在Imgproc包中找到。其語法如下所示:
Imgproc.pyrUp(source, destination, destinationSize); Imgproc.pyrDown(source, destination,destinationSize);
引數描述如下:
| 序號 | 引數及描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
目標影像 它是目標影像。 |
| 3 |
目標尺寸 它是輸出影像的大小。預設情況下,它計算為 Size((src.cols*2), (src.rows*2))。 |
除了 pyrUp 和 pyrDown 方法外,Imgproc 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 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 數字影像處理 - 基本閾值化
閾值化能夠以最簡單的方式實現影像分割。影像分割是指將完整影像劃分為一組畫素,以便每個集合中的畫素具有一些共同的特徵。影像分割在定義物件及其邊界方面非常有用。
本章中,我們將對影像執行一些基本的閾值化操作。
我們使用OpenCV函式threshold。它可以在Imgproc包中找到。其語法如下所示:
Imgproc.threshold(source, destination, thresh , maxval , type);
引數描述如下:
| 序號 | 引數及描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
目標影像 它是目標影像。 |
| 3 |
閾值 它是閾值。 |
| 4 |
最大值 它是將與 THRESH_BINARY 和 THRESH_BINARY_INV 閾值型別一起使用的最大值。 |
| 5 |
型別 可能的型別有 THRESH_BINARY、THRESH_BINARY_INV、THRESH_TRUNC 和 THRESH_TOZERO。 |
除了這些閾值化方法外,Imgproc 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 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 數字影像處理 - 影像形狀轉換
可以使用 OpenCV 輕鬆更改影像的形狀。影像可以翻轉、縮放或沿四個方向中的任何一個旋轉。
為了更改影像的形狀,我們讀取影像並將其轉換為 Mat 物件。其語法如下所示:
File input = new File("digital_image_processing.jpg");
BufferedImage image = ImageIO.read(input);
//convert Buffered Image to Mat.
翻轉影像
OpenCV 允許三種類型的翻轉程式碼,如下所示:
| 序號 | 翻轉程式碼和描述 |
|---|---|
| 1 |
0 0 表示,圍繞 x 軸翻轉。 |
| 2 |
1 1 表示,圍繞 y 軸翻轉。 |
| 3 |
-1 -1 表示,圍繞 x 和 y 軸都翻轉。 |
我們將適當的翻轉程式碼傳遞給Core類中的flip()方法。其語法如下所示:
Core.flip(source mat, destination mat1, flip_code);
flip()方法接受三個引數:源影像矩陣、目標影像矩陣和翻轉程式碼。
除了 flip 方法外,Core 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 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 數字影像處理 - 應用高斯濾波器
本章中,我們將對影像應用高斯濾波器,該濾波器可以模糊影像。我們將使用 OpenCV 函式 GaussianBlur 對影像應用高斯濾波器。它可以在 Imgproc 包中找到。其語法如下所示:
Imgproc.GaussianBlur(source, destination,Size,SigmaX);
函式引數如下所示:
| 序號 | 引數和描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
目標影像 它是目標影像。 |
| 3 |
尺寸 它是高斯核的大小。 |
| 4 |
SigmaX 它是高斯核在 X 方向上的標準差。 |
除了 GaussianBlur 方法外,Imgproc 類還提供了其他方法。下面簡要介紹一下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - 應用方框濾波器
我們應用方框濾波器來模糊影像。方框濾波器可以是 3x3、5x5、9x9 等尺寸。
我們使用OpenCV函式filter2D對影像應用方框濾波器。它可以在Imgproc包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | 引數和描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
深度 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。位置 Point (-1, -1) 預設表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 0。 |
| 7 |
BORDER_DEFAULT 我們預設使用此值。 |
除了 filter2D() 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 的 Box 濾波器進行卷積,如下所示:
大小為 5 的 Box 濾波器
| 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 | 1/25 |
卷積後的影像(使用大小為 5 的 Box 濾波器)
卷積後的影像(使用大小為 9 的 Box 濾波器)
Java 數字影像處理 - 腐蝕和膨脹
在本章中,我們將學習應用兩種非常常見的形態學運算子:膨脹和腐蝕。
我們使用 **OpenCV** 函式 **erode** 和 **dilate**。它們可以在 **Imgproc** 包中找到。其語法如下所示:
Imgproc.erode(source, destination, element); Imgproc.dilate(source, destination, element);
引數描述如下:
| 序號 | 引數及描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
目標影像 它是目標影像。 |
| 3 |
element 它是用於腐蝕和膨脹的結構元素,如果 element=Mat(),則使用 3 x 3 的矩形結構元素。 |
除了 erode() 和 dilate() 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - 應用水印
在本章中,我們將學習兩種在影像上應用水印的方法。這些方法是:
- 應用文字水印
- 應用影像水印
應用文字水印
我們使用 **OpenCV** 函式 **putText** 將文字水印應用於影像。它可以在 **Core** 包中找到。其語法如下所示:
Core.putText(source, Text, Point, fontFace ,fontScale , color);
該函式的引數如下所示:
| 序號 | 引數及描述 |
|---|---|
| 1 |
源 它是源影像。 |
| 2 |
Text 它是將顯示在影像上的字串文字。 |
| 3 |
Point 它是文字在影像上顯示的位置。 |
| 4 |
fontFace 字型型別。例如:FONT_HERSHEY_SIMPLEX、FONT_HERSHEY_PLAIN、FONT_HERSHEY_COMPLEX 等。 |
| 5 |
fontScale 它是字型縮放因子,乘以特定字型的基本大小。 |
| 6 |
color 它是文字顏色。 |
除了 putText 方法外,Core 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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) 它計算二維向量的旋轉角度。 |
| 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);
該函式的引數如下所示:
| 序號 | 引數及描述 |
|---|---|
| 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 數字影像處理 - 理解卷積
卷積是對兩個函式 f 和 g 的數學運算。在這種情況下,函式 f 和 g 是影像,因為影像也是一個二維函式。
執行卷積
為了對影像執行卷積,需要執行以下步驟:
- 僅翻轉一次掩碼(水平和垂直)。
- 將掩碼滑動到影像上。
- 將對應的元素相乘,然後相加。
- 重複此過程,直到計算出影像的所有值。
我們使用 **OpenCV** 函式 **filter2D** 將卷積應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | 引數和描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
深度 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。位置 Point (-1, -1) 預設表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 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 數字影像處理 - Prewitt 運算元
Prewitt 運算元用於影像邊緣檢測。它檢測兩種型別的邊緣:垂直邊緣和水平邊緣。
我們使用 **OpenCV** 函式 **filter2D** 將 Prewitt 運算元應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | 引數和描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
深度 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。位置 Point (-1, -1) 預設表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 0。 |
| 7 |
BORDER_DEFAULT 我們預設使用此值。 |
除了 filter2D 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - Sobel 運算元
Sobel 運算元與 Prewitt 運算元非常相似。它也是一個導數掩碼,用於邊緣檢測。Sobel 運算元用於檢測影像中的兩種邊緣:垂直方向邊緣和水平方向邊緣。
我們將使用 **OpenCV** 函式 **filter2D** 將 Sobel 運算元應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | Argument |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
深度 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。位置 Point (-1, -1) 預設表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 0。 |
| 7 |
BORDER_DEFAULT 我們預設使用此值。 |
除了 filter2D 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - Kirsch 運算元
Kirsch 指南針掩碼是另一種型別的導數掩碼,用於邊緣檢測。此運算子也稱為方向掩碼。在此運算子中,我們取一個掩碼並將其旋轉到所有八個指南針方向以獲取八個方向的邊緣。
我們將使用 **OpenCV** 函式 **filter2D** 將 Kirsch 運算元應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | Argument |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
深度 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。位置 Point (-1, -1) 預設表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 0。 |
| 7 |
BORDER_DEFAULT 我們預設使用此值。 |
除了 filter2D() 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 東
| -3 | -3 | -3 |
| -3 | 0 | -3 |
| 5 | 5 | 5 |
卷積後的影像(Kirsch 東)
此原始影像已使用如下所示的西南邊緣 Kirsch 運算元進行卷積:
Kirsch 西南
| 5 | 5 | -3 |
| 5 | 0 | -3 |
| -3 | -3 | -3 |
卷積後的影像(Kirsch 西南)
Java 數字影像處理 - Robinson 運算元
Robinson 指南針掩碼是另一種型別的導數掩碼,用於邊緣檢測。此運算子也稱為方向掩碼。在此運算子中,我們取一個掩碼並將其旋轉到所有八個主要方向以獲取八個方向的邊緣。
我們將使用 **OpenCV** 函式 **filter2D** 將 Robinson 運算元應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | 引數和描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
深度 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。預設情況下,位置 Point(-1, -1) 表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 0。 |
| 7 |
BORDER_DEFAULT 我們預設使用此值。 |
除了 filter2D 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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());
}
}
}
輸出
執行給定程式碼時,將看到以下輸出:
原始影像
此原始影像已使用如下所示的北邊緣 Robinson 運算元進行卷積:
北方向掩碼
| -1 | 0 | 1 |
| -2 | 0 | 2 |
| -1 | 0 | 1 |
卷積後的影像(Robinson 北)
此原始影像也已使用如下所示的東邊緣 Robinson 運算元進行卷積:
東方向掩碼
| -1 | -2 | -1 |
| 0 | 0 | 0 |
| 1 | 2 | 1 |
卷積後的影像(Robinson 東)
Java 數字影像處理 - Laplacian 運算元
Laplacian 運算元也是一個導數運算子,用於查詢影像中的邊緣。Laplacian 與其他運算子(如 Prewitt、Sobel、Robinson 和 Kirsch)的主要區別在於,這些運算子都是一階導數掩碼,而 Laplacian 是二階導數掩碼。
我們使用 **OpenCV** 函式 **filter2D** 將 Laplacian 運算元應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | Arguments |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
深度 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。位置 Point (-1, -1) 預設表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 0。 |
| 7 |
BORDER_DEFAULT 我們預設使用此值。 |
除了 filter2D() 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, Mat kernel, Point anchor, double delta) 它將影像與核心進行卷積。 |
| 5 |
GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX) 它使用高斯濾波器模糊影像。 |
| 6 |
integral(Mat src, Mat sum) 它計算影像的積分。 |
示例
以下示例演示瞭如何使用 Imgproc 類將 Laplacian 運算元應用於灰度影像。
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());
}
}
}
輸出
執行給定程式碼時,將看到以下輸出:
原始影像
此原始影像已使用如下所示的 Laplacian 負運算元進行卷積:
Laplacian 負
| 0 | -1 | 0 |
| -1 | 4 | -1 |
| 0 | -1 | 0 |
卷積後的影像(Laplacian 負)
此原始影像已使用如下所示的 Laplacian 正運算元進行卷積:
Laplacian 正
| 0 | 1 | 0 |
| 1 | -4 | 1 |
| 0 | 1 | 0 |
卷積後的影像(Laplacian 正)
Java 數字影像處理 - 加權平均濾波器
在加權平均濾波器中,我們賦予中心值更大的權重,因此中心值的貢獻大於其餘值。透過加權平均濾波,我們可以控制影像的模糊程度。
我們使用 **OpenCV** 函式 **filter2D** 將加權平均濾波器應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
filter2D(src, dst, depth , kernel, anchor, delta, BORDER_DEFAULT );
函式引數如下所示:
| 序號 | 引數和描述 |
|---|---|
| 1 |
源影像 它是源影像。 |
| 2 |
dst 它是目標影像。 |
| 3 |
ddepth 它是 dst 的深度。負值(例如 -1)表示深度與源相同。 |
| 4 |
核心 它是將掃描影像的核心。 |
| 5 |
錨點 它是錨點相對於其核心的位置。預設情況下,位置 Point(-1, -1) 表示中心。 |
| 6 |
增量 它是在卷積過程中新增到每個畫素的值。預設值為 0。 |
| 7 |
BORDER_DEFAULT 我們預設使用此值。 |
除了 filter2D() 方法外,Imgproc 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - 建立縮放效果
縮放是放大影像的過程,以便影像中的細節變得更加清晰和突出。
我們使用 **OpenCV** 函式 **resize** 將縮放應用於影像。它可以在 **Imgproc** 包中找到。其語法如下所示:
Imgproc.resize(source,destination, destination.size(),zoomFactor,zoomFactor,Interpolation);
在 resize 函式中,我們傳遞源影像、目標影像及其大小、縮放因子和要使用的插值方法。
可用的插值方法如下所述:
| 序號 | 插值方法和說明 |
|---|---|
| 1 |
INTER_NEAREST 它是最近鄰插值。 |
| 2 |
INTER_LINEAR 它是雙線性插值(預設使用)。 |
| 3 |
INTER_AREA 它是使用像素面積關係進行重取樣。它可能是影像抽取的首選方法,因為它提供更無損的結果。 |
| 4 |
INTER_CUBIC 它是在 4x4 畫素鄰域上進行的雙三次插值。 |
| 5 |
INTER_LANCZOS4 這是一個基於 8x8 畫素鄰域的 Lanczos 插值。 |
除了調整大小方法外,Imgproc 類還提供了其他方法。下面簡要描述了它們:
| 序號 | 方法及描述 |
|---|---|
| 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 影像處理 - 開源庫
在本章中,我們將探討一些廣泛使用的免費影像處理庫,這些庫可以輕鬆地整合到專案中。這些庫包括:
- ImageJ
- Fiji
- Commons Imaging
- ImageMagick
- Endrov
- LeadTools
- OpenCv
ImageJ
ImageJ 是一款公共領域的 Java 影像處理程式,其靈感來自 Macintosh 上的 NIH Image。它可以顯示、編輯、分析、處理、儲存和列印 8 位、16 位和 32 點陣圖像。
下面描述了 ImageJ 的一些基本功能:
| 序號 | 功能與描述 |
|---|---|
| 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 的一些高階功能:
| 序號 | 功能與描述 |
|---|---|
| 1 |
配準 3D 影像 這涉及彈性對齊和蒙太奇、特徵提取、影像穩定器等。 |
| 2 |
分割影像 它提供了超過 35 種類型的分割方法。 |
| 3 |
有用的鍵盤快捷鍵 Fiji 有很多鍵盤快捷鍵。 |
| 4 |
指令碼編寫 允許使用宏、JavaScript、JRuby、Jython、Clojure 和 Beanshell 進行指令碼編寫。 |
| 5 |
開發外掛 使用指令碼編輯器開始開發外掛,然後執行外掛。 |
| 6 |
ImageJ 技巧 ImageJ 易於使用,但有時您希望有一些實際上已實現的功能,但您不知道如何觸發。 |
Commons Imaging
Apache Commons Imaging,以前稱為 Apache Commons Sanselan,是一個庫,可以讀取和寫入各種影像格式,包括快速解析影像資訊(例如大小、顏色、空間、ICC 配置檔案等)和元資料。
下面描述了 ImageJ 的一些基本功能:
| 序號 | 功能與描述 |
|---|---|
| 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 的一些基本功能:
| 序號 | 功能與描述 |
|---|---|
| 1 |
格式轉換 它將影像從一種格式轉換為另一種格式(例如,PNG 到 JPEG)。 |
| 2 |
變換 它可以調整影像大小、旋轉、裁剪、翻轉或修剪影像。 |
| 3 |
透明度 它使影像的某些部分不可見。 |
| 4 |
繪製 它向影像新增形狀或文字。 |
| 5 |
裝飾 它向影像新增邊框或框架。 |
| 6 |
特殊效果 它可以模糊、銳化、閾值或色調影像。 |
| 7 |
動畫 它可以從一組影像建立 GIF 動畫序列。 |
| 8 |
合成 它可以將一個影像疊加在另一個影像上。 |
| 9 |
形狀形態 它提取特徵、描述形狀並在影像中識別模式。 |
| 10 |
加密或解密影像 它將普通影像轉換為難以理解的亂碼並恢復。 |
Endrov
Endrov 是一款多功能影像分析程式。它是獨立編寫的,旨在解決其他免費軟體和許多商業軟體包的許多缺點。
下面描述了 Endrov 的一些基本功能:
| 序號 | 功能與描述 |
|---|---|
| 1 |
檢視資料 它以 2D 和 3D 方式檢視資料。旨在處理複雜的 4D 資料方案和無限數量的通道,其中每個通道可以具有自己的 X、Y 和 Z 解析度。 |
| 2 |
註釋影像 它自動或手動註釋影像,以理解影像並獲取統計資訊。 |
| 3 |
撤消和重做 它可以撤消和重做所有操作。 |
| 4 |
惰性求值 它從一開始就設計用於處理大型影像集。Endrov 使用惰性求值,這主要在研究型程式語言中可用。 |
| 5 |
指令碼語言 它支援圖形化指令碼語言以及傳統指令碼。 |
| 6 |
Java 使用 Java 編寫。外掛架構允許使用新的 Java 外掛輕鬆擴充套件。它可以與 Matlab 互動。 |
| 7 |
格式 它使用 Bio-formats 訪問幾乎所有商業和開放檔案格式。 |
| 8 |
顯微鏡處理 它可以使用一個程式控制所有顯微鏡,並進行即時影像分析。 |
LEADTOOLS
LEADTOOLS 在多個類別中提供了 200 多個影像處理功能,包括文件清理、醫學影像增強、顏色轉換和校正、降噪、邊緣檢測等等。
下面描述了 LEADTOOLS 的一些基本功能:
| 序號 | 功能與描述 |
|---|---|
| 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 的一些基本功能:
| 序號 | 功能與描述 |
|---|---|
| 1 |
平滑影像 這涉及應用 Blur、GaussianBlur、medianBlur 和 bilateral Filter。 |
| 2 |
腐蝕和膨脹 它可以應用兩個非常常見的形態學運算元:膨脹和腐蝕。 |
| 3 |
形態學變換 OpenCV 函式 morphologyEx 用於應用形態學變換,例如開運算、閉運算、TopHat 和 BlackHat 等。 |
| 4 |
影像金字塔 OpenCV 函式 pyrUp 和 pyrDown 用於對給定影像進行下采樣或上取樣。 |
| 4 |
基本的閾值操作 使用 OpenCV 函式 threshold 執行基本的閾值操作。 |
| 5 |
向影像新增邊框 OpenCV 函式 copyMakeBorder 用於設定邊框(影像的額外填充)。 |
| 7 |
重新對映 在 OpenCV 中,函式 remap 提供了一個簡單的重新對映實現。 |
| 8 |
直方圖計算 對於簡單目的,OpenCV 實現函式 calcHist,該函式計算一組陣列(通常是影像或影像平面)的直方圖。它可以操作多達 32 個維度。 |
Java 影像處理 - OpenCV 簡介
OpenCV 在 BSD 許可證下發布,因此它可免費用於學術和商業用途。它具有 C++、C、Python 和 Java 介面,並且支援 Windows、Linux、Mac OS、iOS 和 Android。
OpenCV 專為計算效率而設計,並專注於即時應用。該庫使用最佳化的 C/C++ 編寫,可以利用多核處理。
下面描述了 OpenCV 的一些基本功能:
| 序號 | 功能與描述 |
|---|---|
| 1 |
平滑影像 這涉及應用 Blur、GaussianBlur、medianBlur 和 bilateral Filter。 |
| 2 |
腐蝕和膨脹 它可以應用兩個非常常見的形態學運算元:膨脹和腐蝕。 |
| 3 |
形態學變換 OpenCV 函式 morphologyEx 用於應用形態學變換,例如開運算、閉運算、TopHat 和 BlackHat 等。 |
| 4 |
影像金字塔 OpenCV 函式 pyrUp 和 pyrDown 用於對給定影像進行下采樣或上取樣。 |
| 4 |
基本的閾值操作 它可以使用 OpenCV 函式 threshold 執行基本的閾值操作。 |
| 5 |
向影像新增邊框 OpenCV 函式 copyMakeBorder 用於設定邊框(影像的額外填充)。 |
| 7 |
重新對映 在 OpenCV 中,函式 remap 提供了一個簡單的重新對映實現。 |
| 8 |
直方圖計算 對於簡單目的,OpenCV 實現函式 calcHist,該函式計算一組陣列(通常是影像或影像平面)的直方圖。它可以操作多達 32 個維度。 |
整合 OpenCV
以下步驟說明了如何將 OpenCV 整合到您的應用程式中。
下載 OpenCV
您可以從其官方網站 此處 下載 OpenCV。
建立使用者庫
此外,我們建立了 OpenCV 的使用者庫,以便我們可以在未來的專案中使用它。
啟動 Eclipse
從選單中選擇 Window -> Preferences。
導航到 Java -> Build Path -> User Libraries 並單擊 New。
現在輸入庫的名稱。例如,OpenCV-2.4.6。
之後,選擇您的新使用者庫(即 OpenCV-2.4.6)並單擊 Add External JARs。
瀏覽到 C:\OpenCV-2.4.6\build\java\ 並選擇 opencv-246.jar。新增 jar 後,展開 opencv-246.jar 並選擇 Native library location,然後按 Edit。
選擇 External Folder... 並瀏覽以選擇資料夾 C:\OpenCV-2.4.6\build\java\x64。如果您擁有 32 位系統,則需要選擇 x86 資料夾而不是 x64。
按 Ok,您就完成了。
現在您的使用者庫已建立。現在您可以在任何專案中重用此配置。
建立 OpenCV 專案
在 Eclipse 中建立一個新的 Java 專案。
在 Java Settings 步驟的 Libraries 選項卡下,選擇 Add Library... 並選擇 OpenCV-2.4.6,然後單擊 Finish。
單擊 Finish,您就完成了。
Java 影像處理 - OpenCV 灰度轉換
為了使用 OpenCV 將彩色影像轉換為灰度影像,我們先將影像讀入 **BufferedImage** 並將其轉換為 **Mat** 物件。其語法如下所示:
File input = new File("digital_image_processing.jpg");
BufferedImage image = ImageIO.read(input);
//convert Buffered Image to Mat.
然後,您可以使用 **Imgproc** 類中的 **cvtColor()** 方法將影像從 RGB 格式轉換為灰度格式。其語法如下所示:
Imgproc.cvtColor(source mat, destination mat1, Imgproc.COLOR_RGB2GRAY);
**cvtColor()** 方法接受三個引數,分別是源影像矩陣、目標影像矩陣和顏色轉換型別。
除了 cvtColor 方法外,Imgproc 類還提供了其他方法。它們列在下面:
| 序號 | 方法及描述 |
|---|---|
| 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 depth, 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 數字影像處理 - OpenCV 顏色空間轉換
為了使用 OpenCV 將一個影像的顏色空間更改為另一個顏色空間,我們先將影像讀入 **BufferedImage** 並將其轉換為 **Mat** 物件。其語法如下所示:
File input = new File("digital_image_processing.jpg");
BufferedImage image = ImageIO.read(input);
//convert Buffered Image to Mat.
OpenCv 允許許多顏色轉換型別,所有這些型別都可以在 Imgproc 類中找到。其中一些型別簡要描述如下:
| 序號 | 顏色轉換型別 |
|---|---|
| 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 類還提供了其他方法。它們簡要描述如下:
| 序號 | 方法及描述 |
|---|---|
| 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)