Computer vision in Java? Elementary together with OpenCV


As-salamu alaykum, brothers!

In this post I want to show you how to process images and videos using program code. I will divide the material into 4 steps, we will work in Java. First you need to install the openCV library, which can be downloaded from the official website ‘ https://opencv.org/ ‘, more detailed instructions in the attached video.

Step 1: [Обработка изображения]

Github

Let’s create a popup to display images.

        // Создаём окно для просмотра изображения.
        JFrame window = new JFrame("Window:");
        // Создаём контейнер для изображения.
        JLabel screen = new JLabel();
        // Установлимаем операцию закрытия по умолчанию.
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Делаем окно отображения контента видимым.
        window.setVisible(true);

Load the image by writing the path to it in the method Imgcodecs.imread ()

        // Загружаем изображение, храним его как объект матрицы.
        Mat img = Imgcodecs.imread("src\a_Image\butterfly.png");

We make a stream of transformations over the image, after which we display it in the window created above.

				/* Преобразуем изображение в матрицу байтов с целью
           получить массив байтов (пикселей). */
        MatOfByte buf = new MatOfByte();
        Imgcodecs.imencode(".png", img, buf);

        /* Преобразуем массив пикселей в ImageIcon,
           изображение которое будет отображатся. */
        ImageIcon ic = new ImageIcon(buf.toArray());

        // Привязываем изображение к контейнеру.
        screen.setIcon(ic);
        // Привязываем контейнер к окну отображения.
        window.getContentPane().add(screen);
        window.pack();

Congratulations! The first skill is unlocked, now we can display the .jpg in a pop-up window using java. Let’s not stop there and edit the .jpg.

We will edit the .jpg using the transformation matrix (kernel). The essence is as follows, we represent kernel as a rectangular matrix, each element is a multiplier, different sets of multipliers cause different effects. Kernel goes through all the .jpg elements, pulls them on itself, thereby modifying the .jpg. You can see more clearly in the pictures.

        // Создаём ядро (kernel) для обработки изображения (матрица трансформации).
        Mat kernel = new Mat (20,20, CvType.CV_8UC1, new Scalar(1.0));

Now, based on the kernel, we can use filters, effects and distortions. The processed photo can be resized, cropped and saved.

				// Расширяем светлые и сужаем тёмные области.
        Imgproc.dilate(img, imgEmpty, kernel);
        // Расширяем тёмные и сужаем светлые области.
        Imgproc.erode(img, imgEmpty, kernel);
        // Конвертируем изображение в другое цветовое пространство.
        Imgproc.cvtColor(img, imgEmpty, Imgproc.COLOR_BGR2GRAY);
        // Размываем изображение (параметры ядра должны быть нечетными).
        Imgproc.GaussianBlur(img, imgEmpty, new Size (15,15), 0);
        // Выделяем границы изображения.
        Imgproc.Canny(img, imgEmpty, 2,2);
        // Изменяем размер изображения.
        Imgproc.resize(img, imgEmpty, new Size(200,200));
        // Обрезаем изображение.
        Mat imgCrop = img.colRange(400,600).rowRange(200,400);
        // Обрабатываем часть изображения.
        Imgproc.erode(img.colRange(400,600).rowRange(200,400), img.colRange(400,600).rowRange(200,400), kernel);
        // Сохраняем изображение.
        Imgcodecs.imwrite("src\a_Image\savedImg.png", img);

Step 2: [Обработка видео и видеопотока]

Github

To work with video, let’s create an object of the VideoCapture () class. Its functionality will allow you to display an image from a webcam and play video recordings. As an argument, we pass to the input the path to the video file or the id of the webcam (default: 0).

       /* Инициализируем видеопоток. Класс VideoCapture предназначен для захвата кадра
          из видео или видеопотока. */
        VideoCapture cap = new VideoCapture("src/b_Video/testVideo.mp4");

Referring to the object of the VideoCapture () class in the loop, we extract frames one by one, assign the value of the current frame to the frame matrix.

        // До тех пор пока поступает кадр из видеопотока выполняем следующие действия:
        while (cap.grab()) {
            // Извлекаем кадр из видеопотока.
            cap.read(frame);

The pop-up window should be displayed in a loop, using the following functions, you can draw a line, rectangle, circle and place text on the video:

            // Инициализируем цвет (BGR)
            Scalar color = new Scalar(0,255,0);
            /* Наносим линию на изображение.
               Обрабатываемое изображение, начальная точкаб конечная точкаб цвет, толщина линии */
            Imgproc.line(frame, new Point(0,0), new Point(640,480), color,2);
            //
            Imgproc.rectangle(frame, new Rect(200, 100,240, 280), new Scalar(255, 0, 0),3);
            //
            Imgproc.circle(frame, new Point(320,240), 120, new Scalar(0, 0, 255), 5);
            //
            Imgproc.putText(frame, "SDBproduction", new Point(150,50),
                    4, 1.5, new Scalar(5, 5, 5));

Step 3: [Стриминг видео “UDP Socket”]

Github

To transmit a video stream over a local network, we will build the following logic of work. The server is always in standby mode. The client can connect to the server and start transmitting video, in this case the server will switch to the mode of receiving video from the client, as soon as the client disconnects the server will go into standby mode.

Let’s write the code for the client:

We create a connection from the client side.

 			 	/* Инициализируем видеопоток. Класс VideoCapture предназначен для захвата кадра
           из видео или видеопотока. */
        VideoCapture cap = new VideoCapture(1);

        // Создаём сокет, точку соединения между двумя компьютерами.
        Socket socket = new Socket("192.168.1.159",1234);
        /* Создаём объект DataOutputStream который связываем с нашим сокетом.
           Данный объект позволяет отправлять примитивные типы данных. */
        DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());

We convert each frame to a primitive data type and send it to the server.

       // До тех пор пока поступает кадр из видеопотока выполняем следующие действия:
        while (cap.grab()) {

            try {
                // Извлекаем кадр из видеопотока.
                cap.read(frame);

                /* Преобразуем изображение в матрицу байтов с целью
                   получить массив байтов (пикселей). */
                Imgcodecs.imencode(".png", frame, buf);
                imageData = buf.toArray();

                // Извлекаем размер изображения.
                int dataLength = imageData.length;

                // Отправляем размер изображения.
                dataOutputStream.writeInt(dataLength);
                /* Отправляем изображение в виде массива байтов (пикселей).
                   "последовательность байтов" */
                dataOutputStream.write(imageData);

The server, for its part, consists of two cycles. In the first cycle, we are waiting for a connection to the server from the client. If the connection is established. then inside this loop, the second is launched, which will receive a video stream from the user and output it.

   // Создаём серверный сокет, который будет слушать на заданом порту.
        ServerSocket serverSocket = new ServerSocket(1234);

        // В бесконечном цикле ожидаем подключение к серверу.
        while (true) {

            try {
                /* Ожидаем клиента, если придёт запрос от клиента создаём сокет (точку соединения)
                   чтобы подключится. */
                Socket socket = serverSocket.accept();

                /* Создаём объект DataInputStream который связываем с нашим сокетом.
                   Данный объект позволяет принимать примитивные типы данных. */
                DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());

                // В бесконечном цикле принимаем данные от клиента.
                while (true) {

                    // Принимаем размер изображения.
                    int dataLength = dataInputStream.readInt();

                    // Если изображение существует, то
                    if (dataLength > 0) {

                        /* принимаем изображение в виде массива байтов (пикселей).
                           "последовательность байтов" */
                        byte[] imageData = new byte [dataLength];
                        dataInputStream.readFully(imageData,0,dataLength);

                        /* Преобразуем массив пикселей в ImageIcon,
                           изображение которое будет отображатся. */
                        ic = new ImageIcon(imageData);

                        // Привязываем изображение к контейнеру.
                        screen.setIcon(ic);
                        // Привязываем контейнер к окну отображения.
                        window.setContentPane(screen);
                        window.pack();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

Step 4: [Детекция объектов ” YOLOv4 “]

Github

Convolutional neural network [скачать]

To understand the detection of objects in Java, I suggest you watch my video tutorial.

Thank you so much for your attention!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *