Как считать пиксель java

Обновлено: 04.07.2024

Я ищу самый быстрый способ получить пиксельные данные (int форма int[][] ) с BufferedImage . Моя цель-иметь возможность обращаться к pixel (x, y) из изображения с помощью int[x][y] . Все методы, которые я нашел, не делают этого (большинство из них возвращают int[] s).

Я просто играл с этой же темой, что является самым быстрым способом доступа к пикселям. В настоящее время я знаю два способа сделать это:

    использование BufferedImage в getRGB() метод, как описано в ответе @tskuzzy.

путем доступа к массиву пикселей напрямую с помощью:

если вы работаете с большими изображениями и производительность, первый способ-это абсолютно не выход. The getRGB() метод объединяет значения alpha, red, green и blue в один int, а затем возвращает результат, который в большинстве случаев вы сделаете наоборот, чтобы вернуть эти значения.

второй метод вернет красного, зеленого и синего значений для каждого пикселя, и если есть альфа канал, добавить Альфа-значение. Использование этого метода сложнее с точки зрения расчета индексов, но намного быстрее, чем первый подход.

в моем приложении я смог сократить время обработки пикселей более чем на 90% путем простого переключения с первого подхода на второй!

вот сравнение, которое я настроил для сравнения двух подходов:

можете ли вы угадать выход? ;)

что-то вроде этого?

Я нашел, что ответ Моты дал мне увеличение скорости в 10 раз-так что спасибо Моте.

я завернул код в удобный класс,который принимает BufferedImage в конструкторе и предоставляет эквивалентный метод getRBG(x, y), который делает его заменой кода с помощью BufferedImage.getRGB (x,y)

ответ Mota велик, если ваш BufferedImage не пришел из монохромного растрового изображения. Монохромное растровое изображение имеет только 2 возможных значения для пикселей (например, 0 = черный, 1 = белый). Когда используется монохромное растровое изображение, то

call возвращает необработанные данные массива пикселей таким образом, что каждый байт содержит более одного пикселя.

поэтому, когда вы используете монохромное растровое изображение для создания объекта BufferedImage, это алгоритм, который вы хотите использовать:

Так, как основным языком в этом курсе стал язык Java. Покажу пример того как работать с файлами изображений в Java, чтобы вам не пришлось долго искать как это делать. Для других языков руководства можно найти в Интернете.

Того, что здесь будет показано вполне достаточно чтобы выполнить все лабы.

Итак, поехали.

BufferedImage - класс который представляет изображение, которое хранится в памяти. С помощью этого класса мы будем обрабатывать изображения.

Класс импортируется с пакета java.awt.image:

Для открытия изображения будем использовать два класса: File, ImageIO:

В параметра конструктора класса File, мы должны указать путь до файла. Путь может быть абсолютным, либо относитьтельно корня проекта. Можно открывать картинки с расширением jpg, png, bmp.

После этого в объекта image у нас будет храниться вся картинка, которую мы открыли. Мы можем получить у этой картинки значение любого пикселя в виде цвета в RGB. Чтобы получить цвет какого либо пикселя нам нужен класс Color:

Чтобы получить цвет из пикселя с координатами [20, 20] нужно написать:

Тут также показано как получить значение каждого канала(красный, зеленый, синий) этого цвета. Значения каналов находятся в диапазоне [0, 255].

Значения этих каналов мы будем использовать для обработки изображений. После обработки мы обычно получаем новые значения для каждого канала. Чтобы объединить три канала в один цвет, создаем новый объект класса Color:

Затем, мы можем установить этот цвет как цвет какого-либо пикселя в изображение:

После того, как мы обработали изображение, его нужно сохранить обратно в файл:

Вместо "jpg" можно использовать также "png" или "bmp".

Давайте для примера я напишу приложение, которое будет превращать исходное изображение в черно-белое, используя то, что написано в статье.

Обычно для результирующего изображения создается новый объект типа BufferedImage такого же размера и типа, как исходное изображение:

Преобразователь в черное белое

Возьмем для примера любое цветное изображение. Например:


Поместим его в корень проекта.

Запустив эту программу мы получим новую картинку в той же папке где и исходная картинка. И она должна быть такой:

Special for До этого я пояснял на сухих примерах. Попросили работу с изображениями - ловите.

Постановка учебной задачи.

Дан графический файл (jpeg, png . ). Необходимо сделать с ним некие манипуляции и записать результат в другой файл. Для упрощения рассмотрим три задачи: - получить негатив изображения - получить черно-белый вариант изображения (сбросить цветность) - изменить насыщенность зеленого цвета в изображении. Заметим, что аналогичным способом мы можем, добавляя новые методы реализовывать и другие задачи: - увеличить резкость или размытие - изменить размеры - повернуть по/против часовой. - и другие возможность Фотошопа :) вообщем реализовать любой алгоритм над изображением, насколько у нас хватит фантазии и знания матана (например, распознать количество возможных котиков на картинке).

Немного сухой теории.

Мы рассматриваем растровые изображения (есть еще векторные и другие). То есть, когда файл, помимо собственно заголовка со служебной информацией, хранит прямоугольную матрицу точек. Аналогично экрану современного HD-телевизора у которого разрешение 1920х1080 точек и каждая точка представлена как значения трех составляющих цвета: R(ed), G(reen), B(lue) = Красный, Зеленый и Синий. Эти цвета независимы и данная модель взята из биологии восприятия цвета. В глазу у нас есть колбочки и палочки. Колбочки трех разновидностей (реагируют на соответствующий одной из трех диапазонов длин волн), палочки "обрабатывают" яркость цвета (амплитуду световой волны). В модели RGB палочки отвечают за значение составляющей (0 - отсутствие, 255- самый яркий свет), а колбочки - соответственно в какие из R / G / B помещать соответствующую интенсивность. Например: Отсутствие света - палочки /колбочки не реагируют и RGB=(0,0,0). Яркий белый свет - все колбочки реагируют равномерно, палочки фигеют и RGB = (255,255,255). Серая мышка пробежала - все колбочки реагируют равномерно, палочки реагируют средне и RGB = (127,127,127). Темно-оранжевый - реагируют R и G палочки, палочки едва откликаются, RGB=(30, 30, 0) .

Приступим к практике.
Я писал для примера работы с байтами, поэтому код не вылизан по всем правилам и далеко не оптимален: мы не проверяем входные параметры, не делаем полноценную проверку ошибок и т.п. Писалось в лоб, без рефакторинга. Основной упор - работа с байтами-битами. Напишем, по аналогии задач JavaRush консольную утилиту, которая при вызове в командной строке с соответствующими аргументами модифицирует изображение. Исходное изображение:
вызов с параметрами -n kitten.jpg newkitten.jpg создаст картинку:
вызов с параметрами -b kitten.jpg newkitten.jpg создаст картинку:
вызов с параметрами -gr kitten.jpg newkitten.jpg создаст картинку:

В этом уроке мы рассмотрим несколько доступных библиотек обработки изображений и выполним простую операцию обработки изображений – загрузим изображение и нарисуем на нем фигуру.

Мы попробуем МОКРУЮ (и немного качающуюся) библиотеку, ImageJ, OpenIMAJ и двенадцать обезьян.

2. AWT

AWT-это встроенная библиотека Java, которая позволяет пользователю выполнять простые операции, связанные с отображением, такие как создание окна, определение кнопок и прослушивателей и так далее. Он также включает в себя методы, позволяющие пользователю редактировать изображения. Он не требует установки, так как поставляется с Java.

2.1. Загрузка изображения

Первое, что нужно сделать, это создать объект BufferedImage из изображения, сохраненного на нашем диске:

2.2. Редактирование изображения

В данном конкретном случае нам нужно Graphic 2D расширить ширину фигуры, чтобы сделать ее четко видимой. Мы достигаем этого, увеличивая его свойство s troke . Затем мы задаем цвет и рисуем прямоугольник таким образом, чтобы форма была в десяти пикселях от границ изображения:

2.3. Отображение изображения

Теперь, когда мы нарисовали что-то на нашем изображении, мы хотели бы показать это. Мы можем сделать это с помощью объектов библиотеки Swing. Сначала мы создаем JLabel объект, представляющий область отображения текста или/и изображения:

Затем добавьте наш JLabel в JPanel , который мы можем рассматривать как графического интерфейса на основе Java:

В конце концов, мы добавляем все в JFrame , который является окном, отображаемым на экране. Мы должны установить размер, чтобы нам не приходилось расширять это окно каждый раз, когда мы запускаем нашу программу:

3. ImageJ

ImageJ-это программное обеспечение на базе Java, созданное для работы с изображениями. В нем довольно много плагинов, доступных здесь . Мы будем использовать только API, так как хотим выполнять обработку самостоятельно.

Это довольно мощная библиотека, лучше, чем Swing и AWT, так как целью ее создания была обработка изображений, а не операции с графическим интерфейсом. Плагины содержат много бесплатных алгоритмов, что хорошо, когда мы хотим научиться обработке изображений и быстро увидеть результаты, а не решать математические и оптимизационные задачи, лежащие в основе алгоритмов IP.

3.1. Зависимость Maven

Чтобы начать работу с ImageJ, просто добавьте зависимость в вашего проекта pom.xml файл:

Вы найдете самую новую версию в репозитории Maven .

3.2. Загрузка изображения

Чтобы загрузить изображение, вам нужно использовать метод open Image() static, из I J класс:

3.3. Редактирование изображения

Для редактирования изображения нам придется использовать методы из Image Processor object, прикрепленные к нашему ImagePlus объекту. Думайте об этом как о Графике объекте в AWT:

3.4. Отображение изображения

Вам нужно только вызвать show() метод Image Plus object:

4. OpenIMAJ

4.1. Зависимость Maven

Чтобы начать работу с OpenIMAJ, просто добавьте зависимость в вашего проекта pom.xml файл:

Вы найдете последнюю версию здесь .

4.1. Загрузка изображения

Чтобы загрузить изображение, используйте метод ImageUtilities.readMBF() :

MBF означает многополосное изображение с плавающей запятой (RGB в этом примере, но это не единственный способ представления цветов).

4.2. Редактирование изображения

Чтобы нарисовать прямоугольник, нам нужно определить его форму, которая представляет собой многоугольник, состоящий из 4 точек (верхний левый, нижний левый, нижний правый, верхний правый):

Как вы могли заметить, при обработке изображений ось Y меняется на противоположную. После определения формы нам нужно нарисовать ее:

Метод рисования принимает 3 аргумента: форма, толщина линии и значения канала RGB, представленные массивом Float .

4.3. Отображение изображения

Нам нужно использовать Утилиты отображения :

5. Изображение TwelveMonkeys

Библиотека TwelveMonkeys |/ImageIO предназначена для расширения Java ImageIO API, с поддержкой большего количества форматов.

В большинстве случаев код будет выглядеть так же, как и встроенный код Java, но он будет работать с дополнительными форматами изображений после добавления необходимых зависимостей.

По умолчанию Java поддерживает только эти пять форматов изображений: JPEG , PNG , BMP , WBMP , GIF .

Если мы попытаемся работать с файлом изображения в другом формате, наше приложение не сможет его прочитать и выдаст исключение NullPointerException при доступе к переменной BufferedImage .

Двенадцать обезьян добавляет поддержку следующих форматов: PNG , |/PSD , TIFF , HDR , TIFF , PCX , PICT , SGI , TGA , ICNS , ICO , CUR , Thumbs.db , SVG , WMF .

Для работы с изображениями в определенном формате нам необходимо добавить соответствующую зависимость , например imageio-jpeg или imageio-tiff .

Полный список зависимостей можно найти в документации Двенадцать обезьян .

Давайте создадим пример, который читает изображение .ico . Код будет выглядеть так же, как в разделе AWT , за исключением того, что мы откроем другое изображение:

Чтобы этот пример работал, нам нужно добавить зависимость Двенадцать обезьян , которая содержит поддержку .icon images, которая является зависимостью imageio-bmp , вместе с зависимостью imageio-core :

И это все! Встроенный ImageIO Java API автоматически загружает плагины во время выполнения. Теперь наш проект будет работать и с изображениями .ico .

6. Резюме

Вы познакомились с 4 библиотеками, которые могут помочь вам работать с изображениями. Идя дальше, вы, возможно, захотите поискать некоторые алгоритмы обработки изображений, такие как извлечение краев, повышение контрастности, использование фильтров или распознавание лиц.

Для этих целей, возможно, было бы лучше начать изучать ImageJ или OpenIMAJ. Оба они легко включаются в проект и гораздо более мощны, чем AWT, в отношении обработки изображений.


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

Давайте создадим всплывающее окно для отображения изображений.

Подгрузим изображение прописав путь к нему в метод Imgcodecs.imread()

Производим поток преобразований над изображением, после чего выводим его в окне созданном выше.

Поздравляю! Первый навык разблокирован, теперь мы можем отобразить .jpg в всплывающем окне при помощи джавы. Давайте на этом не будем останавливаться и отредактируем .jpg.

Редактировать .jpg будем при помощи матрицы трансформаций (kernel). Суть состоит в следующем, представим kernel как прямоугольную матрицу, каждый элемент это множитель, разные наборы множителей вызывают разные эфекты. Kernel проходит через все элементы .jpg, домнажает их на себя, тем самым изменяя .jpg. Более наглядно можно посмотреть на картинках.


Теперь на основе kernel мы можем использовать фильтры, эфекты и искожения. Обработываемое фото можно менять по размеру, обрезать и сохранить.

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

Для работы с видео создадим объект класса VideoCapture(). Его функционал позволит отображать изображение с веб-камеры и воспроизводить видеозаписи. В качестве аргумента передаём на вход путь к видеофайлу или id веб-камеры (default: 0).

Обращаясь к объекту класса VideoCapture() в цикле поочередно извлекаем кадры, присваиваем матрице frame значение текущего кадра.

Вывод всплывающего окна следует проводить в цикле, так же используя следующие функции можно нарисрвать линию, прямоугольник, круг и поместить на видео текст:

Шаг 3: [Стриминг видео "UDP Socket"]

Для передачи видеопотока по локальной сети мы выстроим следующую логику работы. Сервер всегда находится в режиме ожидания. Клиент может подключиться к серверу и начать передавать видео, в этом случае сервер переключится в режим приёма видео от клиента, как только клиент отключится сервер уйдет в режим ожидания.

Давайте пропишим код для клиента:

Создаём соединение со стороны клиента.

Каждый кадр конвертируем в примитивный тип данных и отправляем на сервер.

Сервер со своей стороны состоит из двух циклов. В первом цикле ожидаем подключения к серверу от клиента. Если подключение установлено, то внутри этого цикла запускается второй, который будет принимать видеопоток от пользователя и выводить его.

Шаг 4: [Детекция объектов " YOLOv4 "]

Свёрточная нейронная сеть [скачать]
Чтобы разобраться с детекцией объектов на джава предлагаю вам посмотреть мой видеоурок.

Читайте также: