0

Digital Image Processing trong Java

Xử lý ảnh là một phân ngành trong xử lý tín hiệu số với tín hiệu xử lý là ảnh. Đây là một phân ngành khoa học rất phát triển trong những năm gần đây. Xử lý ảnh gồm 4 lĩnh vực chính: xử lý nâng cao chất lựong ảnh, nhận dạng ảnh, nén ảnh và truy vấn ảnh. Sự phát triển của xử lý ảnh đem lại rất nhiều lợi ích cho cuộc sống của con người. Ngày nay xử lý ảnh đã được áp dụng rất rộng rãi trong đời sống như: photoshop, nén ảnh, nén video, nhận dạng biển số xe, nhận dạng khuôn mặt, nhận dạng chữ viết, xử lý ảnh thiên văn, ảnh y tế,....

Các thuật toán về xử lý ảnh thường rất phức tạp, kể cả việc nén ảnh để giảm dung lượng lưu trữ mà vẫn giữ được chất lượng ảnh tốt cũng là vấn đề hóc búa. Mình cũng chỉ mới tìm hiểu sơ qua, vậy nên trong bài viết này mình sẽ giới thiệu một số khái niệm đơn giản về xử lý ảnh trong Java.

Đầu tiên, chắc hẳn ai cũng đã từng nghe qua về pixels, pixel là đơn vị nhỏ nhất của một hình ảnh, và chẳng ai ngạc nhiên khi ảnh kỹ thuật số là tập hợp của rất nhiều pixels 😃. Đó chỉ là bề nổi, thực ra trong mỗi pixel ảnh có chứa bốn thành phần Alpha (độ trong suốt), Red, Green, Blue và nói ngắn gọn thì là (ARGB). Giá trị của tất cả các thành phần nằm trong khoảng 0 - 255. 0 có nghĩa là thành phần vắng mặt và 255 nghĩa là thành phần có đầy đủ. Chúng ta có thể lấy các giá trị pixel của hình ảnh và thiết lập các giá trị pixel trong một hình ảnh sử dụng một số ngôn ngữ lập trình.

Chú thích: Vì, 2^8 = 256 và giá trị của các thành phần pixel nằm giữa 0 và 255, vì vậy chúng ta chỉ cần 8 bit để lưu các giá trị. Do đó, tổng số bit cần thiết để lưu các giá trị ARGB là 8 * 4 = 32 bit hoặc 4 byte. Theo thứ tự có nghĩa là giá trị Alpha được xếp ở 8bit ngoài cùng bên trái, tiếp đến 8bit lưu giá trị RED, 8bit lưu giá trị Green, Blue sẽ là 8 bit ngoài cùng bên phải.

Vì vậy vị trí bit: Đối với thành phần Blue là 7-0, Đối với thành phần Green là 15-8, Đối với thành phần Red là 23-16, Đối với thành phần Alpha là 31-24,

Dưới đây là hình ảnh minh họa về các thành phần trong 1pixel

Tiếp theo là ví dụ minh họa về việc lấy và thiết lập giá trị của 1 pixel. Lưu ý: hãy set đường dẫn tới ảnh trên ổ cứng của bạn ("/home/framgia/Pictures/20160707_110658.jpg" -> your image)

package img.processing;

import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

public class GetSetPixels {
    public static void main(String args[]) throws IOException {
        BufferedImage img = null;
        File f = null;

        // read image
        try {
            f = new File("/home/framgia/Pictures/20160707_110658.jpg");
            img = ImageIO.read(f);
        } catch (IOException e) {
            System.out.println(e);
        }

        /* get pixel value */
        int p = img.getRGB(0, 0);

        /* We, have seen that the components of pixel occupy
           8 bits. To get the bits we have to first right shift
           the 32 bits of the pixels by bit position(such as 24
           in case of alpha) and then bitwise ADD it with 0xFF.
           0xFF is the hexadecimal representation of the decimal
           value 255.  */

        // get alpha
        int a = (p >> 24) & 0xff;

        // get red
        int r = (p >> 16) & 0xff;

        // get green
        int g = (p >> 8) & 0xff;

        // get blue
        int b = p & 0xff;

        /*
        for simplicity we will set the ARGB
        value to 255, 100, 150 and 200 respectively.
        */
        a = 255;
        r = 100;
        g = 150;
        b = 200;

        // set the pixel value
        p = (a << 24) | (r << 16) | (g << 8) | b;
        img.setRGB(0, 0, p);

        // write image
        try {
            f = new File("G:\\Out.jpg");
            ImageIO.write(img, "jpg", f);
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

Một vài ví dụ về xử lý ảnh

Ảnh gốc:

package img.processing;

import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
 
public class Grayscale
{
    public static void main(String args[])throws IOException
    {
        BufferedImage img = null;
        File f = null;
 
        // read image
        try
        {
            f = new File("/home/framgia/Pictures/20160707_110658.jpg");
            img = ImageIO.read(f);
        }
        catch(IOException e)
        {
            System.out.println(e);
        }
 
        // get image's width and height
        int width = img.getWidth();
        int height = img.getHeight();
 
        // convert to greyscale
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                // Here (x,y)denotes the coordinate of image 
                // for modifying the pixel value.
                int p = img.getRGB(x,y);
 
                int a = (p>>24)&0xff;
                int r = (p>>16)&0xff;
                int g = (p>>8)&0xff;
                int b = p&0xff;
 
                // calculate average
                int avg = (r+g+b)/3;
 
                // replace RGB value with avg
                p = (a<<24) | (avg<<16) | (avg<<8) | avg;
 
                img.setRGB(x, y, p);
            }
        }
 
        // write image
        try
        {
            f = new File("/home/framgia/Pictures/20160707_110658 Grey.jpg");
            ImageIO.write(img, "jpg", f);
        }
        catch(IOException e)
        {
            System.out.println(e);
        }
    }
}

Grey scale:

package img.processing;

//Java program to demonstrate colored to negative conversion
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

public class Negative
{
 public static void main(String args[])throws IOException
 {
     BufferedImage img = null;
     File f = null;

     // read image
     try
     {
         f = new File("/home/framgia/Pictures/20160707_110658.jpg");
         img = ImageIO.read(f);
     }
     catch(IOException e)
     {
         System.out.println(e);
     }

     // Get image width and height
     int width = img.getWidth();
     int height = img.getHeight();

     // Convert to negative
     for (int y = 0; y < height; y++)
     {
         for (int x = 0; x < width; x++)
         {
             int p = img.getRGB(x,y);
             int a = (p>>24)&0xff;
             int r = (p>>16)&0xff;
             int g = (p>>8)&0xff;
             int b = p&0xff;

             //subtract RGB from 255
             r = 255 - r;
             g = 255 - g;
             b = 255 - b;

             //set new RGB value
             p = (a<<24) | (r<<16) | (g<<8) | b;
             img.setRGB(x, y, p);
         }
     }

     // write image
     try
     {
         f = new File("/home/framgia/Pictures/20160707_110658 Negative.jpg");
         ImageIO.write(img, "jpg", f);
     }
     catch(IOException e)
     {
         System.out.println(e);
     }
 }
}

Negative:

Ngoài ra còn rất nhiều các thuật toán và thư viện để làm việc với ảnh chúng ta có thể sử dụng, ví dụ như OpenCV, ImageJ, .........


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.