Примитивы и объекты . Объектно-ориентированное программирование на Java. Платформа Java SE
Теперь в качестве обобщения.
В Java есть два общих типа данных: примитивы и объекты.
Примитив – это тип данных Java, которые считаются простейшей формой данных.
Данные этого типа хранятся непосредственно в памяти.
Это данные типа int, char, double и boolean.
И когда вы создаете новую переменную типа int, которая является примитивом, компьютер выделяет область в памяти с именем и значением этого int прямо там.
Поэтому всякий раз, когда вы передаете переменную в качестве параметра или копируете ее, вы копируете значение этой переменной.
Поэтому вы создаете совершенно новую версию этой переменной каждый раз, когда вы манипулируете ей.
Так как примитивы такие простые, мы можем выполнять с ними прямые математические операции, такие как сложение, вычитание, деление, и так далее.
Теперь, что такое объект?
Объектом является гораздо более сложный тип данных, потому что на самом деле это способ хранения нескольких фрагментов связанной информации и различных вещей, которые вы можете делать с этой информацией под одним типом данных.
Такие вещи, как String, Array, Scanner и ArrayList считаются объектами.
И все они начинаются с большой буквы в Java, чтобы обозначить их как объекты.
Когда вы создаете новую переменную типа объект, например, для массива, компьютер выделяет область памяти для ссылки на то, где этот код на самом деле собирается хранить эти данные.
Затем, когда вы передаете это значение в качестве параметра, вы передаете ссылку, а не фактические данные.
И это потому, что объекты намного больше примитивов, и постоянно копировать их очень затратно.
Поэтому вам всегда нужно понимать, когда вы копируете ссылку на объект или сами данные объекта.
Поскольку объекты сложнее примитивов, вы не можете выполнять такие вещи, как сложение и вычитание, как с простыми числами.
Но, поскольку объекты имеют свое поведение, вам просто нужно взглянуть на методы объекта, чтобы узнать, что вы можете с этим объектом сделать.
Например, если вы хотите узнать, сколько символов в строке, вы вызываете метод length.
Каждый объект имеет свой собственный набор моделей поведения.
И есть одна вещь, о которой нужно знать.
Это специальное ключевое слово null.
Null – это просто слово, которое означает отсутствие объекта.
По сути, это значение 0 для объекта.
Точно так же, как 0 – это значение 0 для int или 0.0 – это значение 0 для double.
Null – это значение 0 для всех типов объектов.
Предположим, мы создаем новый массив строк.
Если мы создадим новый массив символов, мы знаем, что он хранит значения нулей по умолчанию.
Но что он хранит в случае, когда мы создаем массив строк?
Это Null.
Это то, что автоматически заполняется в массив, что означает, объект может быть здесь, но его нет здесь и сейчас.
Это важно знать, потому что вы можете столкнуться с очень распространенным типом исключения Null Pointer.
Обычно это происходит, когда вы пытаетесь выполнить метод объекта, который является нулевым.
Например, мы хотим получить длину строки, которая хранится в этом массиве.
Там нет строки, поэтому мы получаем так называемое исключение Null Pointer.
Вы не можете назвать длину того, чего не существует.
Имейте в виду, что null означает объект, а не пустой объект.
Например, вы можете вызвать метод length для пустой String.
Это длина равна нулю.
Но нет такой длины, как длина того, чего не существует.
Просто важно знать, что null означает, что здесь нет объекта.
И нам нужно туда его поместить.
Теперь, когда мы понимаем, что такое примитив и что такое объект, важно понять, как компьютер рассматривает эти два типа переменных в своей собственной памяти.
Потому что это оказывает огромное влияние на то, как вы их программируете.
Представим себе, что это память компьютера.
На самом деле это похоже на то, как выглядит память компьютера.
Это общая сетка с адресами для каждого отдельного местоположения, очень похожая на массив.
Когда вы создаете новую переменную примитивного типа, компьютер занимает одно место в памяти и просто помещает эту информацию прямо там, имя и значение переменной.
Когда вы создаете новый объект, он является динамическим.
Он может расти и сокращаться, он может быть большим.
Поэтому компьютер должен придумать особый способ поддерживать этот объект в собственной памяти.
Поэтому, при создании, например, нового массива, компьютер сначала находит место в своей памяти для хранения адреса, где он будет хранить этот массив.
И затем он занимает целую секцию памяти для какого-либо большого объекта.
И, теперь у нас есть массив, находящийся в памяти, где одна из ячеек хранит адрес, где находятся реальные данные.
Это и есть ссылка.
Таким образом существует большое различие между примитивами и объектами.
Примитивы хранятся непосредственно в памяти, как только вы создаете примитив.
Они настолько малы, что это имеет смысл.
Когда вы копируете переменную примитивного типа и меняете ее значение, первоначальное значение никак не меняется.
Между ними нет реальной связи.
Это будут две совершенно разные переменные.
Как вы можете себе представить, объекты функционируют по-другому.
Вместо того, чтобы выделять пространство для фактического значения, объекты занимают пространство в памяти для ссылки на место, где хранится информация объекта.
Поэтому, если я создаю новый массив, а затем создаю другой массив, и устанавливаю его равным первому массиву, что копируется?
Компьютер копирует ссылку.
Теперь у меня есть две переменные, которые указывают на одну и ту же информацию.
Поэтому, если я что-то изменяю в массиве z, изменится и массив y, и наоборот.
Вы просто скопировали адрес, где находится информация.
Поэтому, если я создам объект и передам его как параметр в метод, я передам ссылку или адрес.
И любые изменения, которые я сделаю в этом методе с объектом, будут отражены в первоначальном объекте.
Мне даже не нужно возвращать его в методе.
Как было сказано ранее, массивы – это объекты. Однако, у них нет полезных методов внутри объекта Array.
Для этого в Java есть класс Arrays,
который содержит набор статических вспомогательных методов для работы с числами, схожих с тем, как в классе Math есть набор статических вспомогательных методов для работы с числами.
Вот несколько популярных методов из класса Arrays.
Метод toString возвращает строковое представление массива.
Метод equals определяет, одинаковы ли два массива.
Метод sort сортирует элементы.
Метод binarySearch выполняет поиск элемента по значению и возвращает индекс элемента в случае успеха, или отрицательное целое в случае, если такого элемента нет.
Для работы метода binarySearch необходимо, чтобы массив был уже отсортирован.
Класс Arrays находится в пакете java. util, и если вы хотите его использовать, вы должны добавить строку import java. util.* в начало Java файла.
Давайте рассмотрим пример использования пары методов из класса Arrays.
В этой задаче мы хотим вернуть медианное значение для множества чисел, где медиана – это среднее значение, когда числа отсортированы.
Для решения задачи, сначала мы создадим копию массива, т.о. мы не изменим оригинальный массив.
После создания копии, мы отсортируем массив. Потом мы просто сможем получить медианное значение, которое представляет собой просто средний элемент массива нечетной длины, или арифметическое среднее двух средних элементов массива четной длины.
Вот наш метод median, который принимает массив целых чисел в качестве аргумента, и возвращает значение типа double.
Мы возвращаем тип double, т.к. у нас может быть усреднение двух целых чисел.
Метод начинается с создания копии массива-аргумента вызовом метода copyOf класса Arrays.
Этот метод создаст копию массива с количеством элементов, которое указанно вторым аргументом.
В данном случае, мы создаем полную копию массива numbers.
После того, как копия сделана, мы сортируем ее, вызывая метод Arrays. sort.
Мы находим средний элемент массива, используя целочисленное деление, и затем определяем, четная ли длина у массива или нечетная.
Если длина четная, мы возвращаем среднее значение двух центральных элементов.
В этом случае, мы делим на 2.0, чтобы получить число с плавающей запятой.
Если длина нечетная, мы просто возвращаем центральный элемент отсортированного массива.
В заключение, давайте коротко обсудим массивы объектов.
Как упоминалось ранее, когда массив создан, его элементы инициализируются нулем 0 такого же типа, что и базовый тип массива.
Для массивов объектных типов, значение при инициализации – это специальное значение null.
Значение null просто означает, что там не пока объекта.
Например, если мы создадим массив coordinate, это массив трех элементов типа Point.
Все три элемента будут проинициализированы значением null.
Перед тем, как пользоваться этим массивом, нам нужно заменить все значения null реальными объектами Point.
Т.о. массивы объектного типа требуют инициализации в два этапа.
На первом тапе, вы создаете объект массива, а на втором этапе, вы создаете объект базового типа для каждого элемента массива.
В образце кода, первым шагом является создание массива coordinate.
Затем, мы выполняем второй шаг с помощью цикла, в котором создается реальный объект класса Point для элемента 0, 1 и 2.
Массивы – полезный инструмент.
Однако они имеют некоторые ограничения.
Когда вы сначала создаете массив, вам нужно выбрать его размер.
И как только вы выберете размер массива, его нельзя изменить.
Это усложняет ситуацию, если у вас есть динамический набор информации, входящий и выходящий из вашей структуры данных.
Что, если вы не знаете, сколько всего будет элементов в конце концов?
Кроме того, если вы захотите, скажем, вставить что-то в середину массива, вы должны освободить место для этого.
Это означает, что вы должны сдвинуть все остальные элементы дальше по массиву.
Было бы неплохо, если бы существовала структура данных, которая обеспечивала бы легкий доступ и организацию массива, но при этом предоставляла бы всю гибкость, которая вам нужна.
Такая структура данных в Java есть и это список.
Список представляет собой упорядоченную последовательность элементов, как и массив.
При этом, он добавляет функциональность, позволяющую ему расти и уменьшаться и вставлять элемент в середину без необходимости делать какие-либо изменения.
Также вы можете удалить элемент внутри списка.
Первый тип списка, так как в Java существует много типов списков, это ArrayList.
ArrayList хранит информацию в массиве, но при этом предоставляет дополнительную функциональность списка.
Вот несколько сравнений использования ArrayList и простого массива.
С массивом вы начнете с типа и затем набор скобок, а затем его размер.
С ArrayList, вам просто нужно знать, какой тип информации вы собираетесь хранить в нем, а затем вы создаете новый ArrayList.
И он будет расти и сокращаться по мере необходимости.
Не нужно передавать его длину.
Чтобы добавить значение в массив вы должны найти в нем место и добавить в это место значение.
В ArrayList вы можете просто сказать add и затем добавить все, что захотите, в ArrayList.
Он сам знает, где находится свободное пространство.
Вы также можете получить элемент, как и массив, используя индекс.
ArrayList поддерживает индексы для каждого из элементов, как и массив.
В ArrayList вы должны передать тип информации, которую он собирается хранить, в качестве параметра.
И это отлично подходит для объектов.
Но как насчет примитивов?
К сожалению, вы не можете просто создать ArrayList из, например, int.
Поэтому вам нужно использовать так называемый класс-оболочку, который является простым классом, хранящим только int внутри него.
Это класс Integer.
То же самое существует для double и char.
ArrayList поставляется с огромным набором методов, чтобы сделать жизнь проще. 32—1, так что вы не сможете использовать всю длину массива.
ArrayList имеет переменную размера, которую он всегда поддерживает.
Вы добавляете элемент в массив и удаляете, при этом изменяется переменная размера.
Данный текст является ознакомительным фрагментом.
освойте Python и OpenCV с помощью этого невероятного пошагового — Machine learning на vc.ru
5 просмотров
Оглавление
I. Введение
A. Краткий обзор распознавания изображений и его приложений
B. Введение в Python и OpenCV для распознавания изображений
II. Настройка среды
A. Установка Python и необходимых пакетов
Б. Настройка OpenCV
III. Загрузка и отображение изображений
А. Чтение изображений с помощью OpenCV
B. Отображение изображений с помощью OpenCV
IV. Предварительная обработка изображения
A. Преобразование изображений в оттенки серого
Б. Изменение размера изображений
C. Применение фильтров и обнаружение границ
V. Извлечение признаков
A. Введение в методы извлечения признаков
B. Реализация извлечения функций SIFT, SURF и ORB с помощью OpenCV
VI. Обучение классификатора
A. Разделение набора данных на наборы для обучения и тестирования
B. Выбор классификатора (например, SVM, KNN)
C. Обучение классификатора с использованием извлеченных признаков.
VII. Тестирование и оценка классификатора
VIII. Реальные приложения и тематические исследования
A. Обнаружение и отслеживание объектов
B. Распознавание лиц и биометрия
C. Оптическое распознавание символов (OCR)
D. Сегментация изображения и понимание сцены
IX. Советы по повышению точности и производительности
A. Методы дополнения данных
B. Настройка гиперпараметров
C. Ансамблевое обучение и наложение моделей
X. Расширенные темы и дальнейшее изучение
А. Глубокое обучение для распознавания изображений с помощью Python и TensorFlow
B. Внедрение пользовательских алгоритмов распознавания изображений
C. Интеграция распознавания изображений в веб-приложения
XI. Заключение
A. Резюме ключевых понятий и методов, рассмотренных
B. Будущее распознавания изображений и роль Python в этой области
C. Поощрение к дальнейшему обучению и экспериментированию
I. Введение
A. Краткий обзор распознавания изображений и его приложений.
Распознавание изображений, также известное как компьютерное зрение, представляет собой быстрорастущую область искусственного интеллекта, которая включает анализ и интерпретацию цифровых изображений и видео с использованием алгоритмов и моделей глубокого обучения. Это стало важной технологией в различных отраслях, таких как здравоохранение, автомобилестроение, наблюдение и развлечения, для автоматизации задач, улучшения процесса принятия решений и повышения качества обслуживания пользователей. Некоторые из приложений распознавания изображений включают в себя:
- Обнаружение и распознавание объектов : идентификация и определение местоположения объектов на изображении или видео.
- Распознавание лиц и биометрия: распознавание и проверка людей на основе их черт лица или других биометрических данных.
- Оптическое распознавание символов (OCR) : извлечение текста из изображений и преобразование его в редактируемые форматы.
- Сегментация изображения и понимание сцены : разделение изображения на значимые части и анализ его контекста.
- Автономные транспортные средства и дроны: использование компьютерного зрения для навигации и обхода препятствий
- Медицинская визуализация и диагностика: анализ медицинских изображений для выявления заболеваний и аномалий
- Дополненная и виртуальная реальность: наложение цифрового контента на реальный мир с помощью входов с камеры.
B. Введение в Python и OpenCV для распознавания изображений.
Python — популярный язык программирования для машинного обучения и обработки данных. благодаря своей простоте, удобочитаемости и богатым библиотекам. OpenCV (библиотека компьютерного зрения с открытым исходным кодом) — это мощная библиотека с открытым исходным кодом, которая предоставляет широкий спектр функций и инструментов для управления, анализа и обработки изображений и видео. Она поддерживает различные платформы и языки, включая Python, C++ и Java, и широко используется в академических и промышленных исследованиях. В этом руководстве основное внимание будет уделено использованию Python и OpenCV для выполнения задач распознавания изображений, включая загрузку и отображение изображений, предварительную обработку изображений, извлечение признаков, обучение и тестирование классификатора, а также оценку его производительности. К концу этого руководства у вас будет прочная основа для распознавания изображений с помощью ИИ и практические навыки для применения его к реальным задачам.
II. Настройка среды
A. Установка Python и необходимых пакетов
Прежде чем вы сможете начать работать с Python и OpenCV, вам необходимо настроить среду разработки. Первый шаг — установить Python и некоторые необходимые пакеты. Вы можете загрузить последнюю версию Python с официального сайта и установить её на свой компьютер. После того, как вы установили Python, вам нужно будет установить следующие пакеты с помощью pip, диспетчера пакетов Python:
- NumPy : мощная библиотека для числовых вычислений, обеспечивающая поддержку массивов и матриц.
- Matplotlib : библиотека для создания визуализаций, таких как диаграммы и графики.
- OpenCV : библиотека для задач компьютерного зрения, предоставляющая широкий набор функций и инструментов для управления, анализа и обработки изображений и видео.
Вы можете установить эти пакеты, выполнив следующие команды в командной строке или терминале:
pip install numpy pip install matplotlib pip install opencv-python
B. Настройка OpenCV
После установки необходимых пакетов вам необходимо настроить OpenCV для работы с Python. Существуют разные способы установки OpenCV в зависимости от вашей операционной системы и предпочтений. Одним из популярных вариантов является использование готовых двоичных файлов, предоставляемых организацией OpenCV. Вы можете загрузить соответствующую версию OpenCV для вашей системы с официального сайта и установить её, следуя предоставленным инструкциям.
Другой вариант — собрать OpenCV из исходников , что даёт больше гибкости и возможностей настройки, но требует больше усилий и знаний. Вы можете найти инструкции по сборке OpenCV из исходного кода на веб-сайте OpenCV.
После установки OpenCV вы готовы начать работу с изображениями с помощью Python и OpenCV.
III. Загрузка и отображение изображений
А. Чтение изображений с использованием OpenCV
Первым шагом в распознавании изображений является загрузка изображения в ваш скрипт Python . OpenCV предоставляет функцию cv2.imread(), которая позволяет считывать изображение из файла и сохранять его в виде массива NumPy. Функция принимает имя файла в качестве входных данных и возвращает массив NumPy, представляющий изображение.
Вот пример фрагмента кода, который загружает изображение и отображает его размеры :
import cv2 # load an image img = cv2.imread(‘image.jpg’) # get the dimensions of the image height, width, channels = img.shape print(f»Image dimensions: {width}x{height}, {channels} channels»)
B. Отображение изображений с помощью OpenCV
После того, как вы загрузили изображение в свой скрипт Python, вы можете отобразить его с помощью OpenCV. Функция cv2.imshow()позволяет отображать изображение в окне. Функция принимает два аргумента: заголовок окна и изображение.
Вот пример фрагмента кода, отображающего изображение в окне:
import cv2 # load an image img = cv2.imread(‘image.jpg’) # display the image in a window cv2.imshow(‘Image’, img) # wait for a key press to close the window cv2. waitKey(0) cv2.destroyAllWindows()
Функция cv2.waitKey()ожидает нажатия клавиши перед закрытием окна. Аргумент 0 указывает, что окно будет оставаться открытым, пока не будет нажата клавиша. Функция cv2.destroyAllWindows()закрывает все окна, созданные OpenCV.
IV. Предварительная обработка изображения
А. Преобразование изображений в оттенки серого
Перед выполнением задач распознавания изображений часто полезно преобразовать изображение в оттенки серого . Изображения в градациях серого имеют один канал вместо трех (RGB), что упрощает их обработку и анализ. OpenCV предоставляет функцию cv2.cvtColor(), которая позволяет преобразовать изображение в оттенки серого.
Вот пример фрагмента кода, который преобразует изображение в оттенки серого:
# load an image img = cv2.imread(‘image.jpg’) # convert the image to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # display the grayscale image in a window cv2.imshow(‘Grayscale Image’, gray) # wait for a key press to close the window cv2. waitKey(0) cv2.destroyAllWindows()
B. Изменение размера изображений
Ещё один распространенный этап предварительной обработки — изменение размера изображения до определённого. Изменение размера изображения может помочь уменьшить его вычислительную сложность и повысить производительность. OpenCV предоставляет функцию cv2.resize(), которая позволяет изменять размер изображения.
Вот пример фрагмента кода, который изменяет размер изображения до определённого:
# load an image img = cv2.imread(‘image.jpg’) # resize the image resized = cv2.resize(img, (500, 500)) # display the resized image in a window cv2.imshow(‘Resized Image’, resized) # wait for a key press to close the window cv2.waitKey(0) cv2.destroyAllWindows()
C. Применение фильтров и определение границ
Ещё одним важным этапом предварительной обработки является применение фильтров к изображению для удаления шума и улучшения его характеристик. OpenCV предоставляет широкий спектр фильтров и алгоритмов обнаружения границ, которые можно использовать для предварительной обработки изображений.
Вот пример фрагмента кода, который применяет к изображению фильтр Гаусса и обнаружение границ Канни:
import cv2 import numpy as np # load an image img = cv2.imread(‘image.jpg’) # apply a Gaussian filter to the image blur = cv2.Gaussian
V. Извлечение признаков:
A. Введение в методы извлечения признаков:
Извлечение признаков — это процесс извлечения важных и информативных признаков из изображения, которые можно использовать для дальнейшей обработки, такой как обнаружение объектов, классификация или сегментация. В компьютерном зрении извлечение признаков является важным шагом в большинстве задач распознавания изображений.
В OpenCV доступны различные методы извлечения признаков , в том числе:
- Масштабно-инвариантная трансформация признаков ( SIFT )
- Ускоренные надёжные функции ( SURF )
- Ориентированный FAST и Rotated BRIEF ( ORB )
B. Реализация извлечения функций SIFT, SURF и ORB с помощью OpenCV.
В этом разделе мы реализуем извлечение функций SIFT, SURF и ORB с использованием OpenCV на Python.
Во-первых, нам нужно установить пакет OpenCV-contrib, который содержит реализации этих методов извлечения функций. Мы можем установить его с помощью pip:
pip install opencv-contrib-python
После установки мы можем использовать следующие фрагменты кода для извлечения функций с использованием методов SIFT, SURF и ORB:
1. SIFT:
import cv2 # Load the image img = cv2.imread(‘image.jpg’) # Create a SIFT object sift = cv2.xfeatures2d.SIFT_create() # Detect keypoints and compute descriptors kp, des = sift.detectAndCompute(img, None) # Draw keypoints on the image img_with_kp = cv2.drawKeypoints(img, kp, None) # Display the image with keypoints cv2.imshow(‘Image with SIFT keypoints’, img_with_kp) cv2.waitKey(0) cv2.destroyAllWindows()
2. SURF:
import cv2 # Load the image img = cv2.imread(‘image.jpg’) # Create a SURF object surf = cv2.xfeatures2d.SURF_create() # Detect keypoints and compute descriptors kp, des = surf. detectAndCompute(img, None) # Draw keypoints on the image img_with_kp = cv2.drawKeypoints(img, kp, None) # Display the image with keypoints cv2.imshow(‘Image with SURF keypoints’, img_with_kp) cv2.waitKey(0) cv2.destroyAllWindows()
3. ORB:
import cv2 # Load the image img = cv2.imread(‘image.jpg’) # Create an ORB object orb = cv2.ORB_create() # Detect keypoints and compute descriptors kp, des = orb.detectAndCompute(img, None) # Draw keypoints on the image img_with_kp = cv2.drawKeypoints(img, kp, None) # Display the image with keypoints cv2.imshow(‘Image with ORB keypoints’, img_with_kp) cv2.waitKey(0) cv2.destroyAllWindows()
В приведённых выше фрагментах кода мы сначала загружаем изображение с помощью cv2.imread(). Затем мы создаем объект соответствующей техники извлечения признаков,используя cv2.xfeatures2d.SIFT_create(), cv2.xfeatures2d.SURF_create()и cv2.ORB_create(). Затем мы используем функцию detectAndCompute() для обнаружения ключевых точек и вычисления дескрипторов для изображения. Наконец, мы рисуем обнаруженные ключевые точки на изображении с помощью cv2.drawKeypoints()и отображаем изображение с помощью cv2.imshow().
После того, как мы извлекли функции с помощью одного или нескольких методов, мы можем использовать их для обучения классификатора распознаванию изображений , как мы обсудим в следующем разделе.
Стоит отметить, что хотя SIFT и SURF являются популярными методами извлечения признаков, они запатентованы и требуют лицензии для коммерческого использования. С другой стороны, ORB — это бесплатная альтернатива с открытым исходным кодом, которая обеспечивает производительность, аналогичную SIFT и SURF.
VI. Обучение классификатора
A. Разделение набора данных на наборы для обучения и тестирования.
Перед обучением классификатора нам нужно разделить наш набор данных на наборы для обучения и тестирования. Обучающий набор используется для обучения классификатора, а тестовый набор используется для оценки его производительности.
Мы можем использовать функцию train_test_split() из библиотеки scikit-learn, чтобы разделить наш набор данных. Функция принимает функции и соответствующие метки в качестве входных данных и возвращает наборы для обучения и тестирования:
from sklearn.model_selection import train_test_split # Split the dataset into training and testing sets X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42)
В приведённом выше коде features и labels представляют собой массивы извлечённых функций и соответствующих меток для каждого изображения соответственно. test_size указывает часть набора данных, которая будет использоваться для тестирования, а random_state обеспечивает воспроизводимость разделения.
B. Выбор классификатора (например, SVM, KNN).
Существуют различные классификаторы, доступные для распознавания изображений, такие как машины опорных векторов (SVM), метод k-ближайших соседей (KNN), случайные леса и нейронные сети. Выбор классификатора зависит от конкретной задачи и набора данных.
Например, SVM — популярный выбор для задач классификации изображений с наборами данных малого и среднего размера. KNN, с другой стороны, представляет собой простой и интуитивно понятный алгоритм, который может хорошо работать для пространств признаков низкой размерности.
C. Обучение классификатора с использованием извлеченных признаков.
После того, как мы разделили набор данных и выбрали классификатор, мы можем обучить классификатор, используя извлеченные признаки и соответствующие метки. Для этого мы можем использовать метод объекта-классификатора fit():
from sklearn.svm import SVC # Create an SVM classifier clf = SVC() # Train the classifier using the training set clf.fit(X_train, y_train)
В приведённом выше коде мы создаём объект классификатора SVM с помощью SVC()конструктора, а затем обучаем классификатор с помощью метода fit() с обучающими функциями и метками.
VII. Тестирование и оценка классификатора
После обучения классификатора мы можем использовать тестовый набор для оценки его производительности. Мы можем использовать метод объекта-классификатора predict(), чтобы предсказать метки для тестового набора, а затем вычислить различные показатели, такие как точность и отзыв:
from sklearn.metrics import accuracy_score, precision_score, recall_score # Predict the labels for the testing set y_pred = clf.predict(X_test) # Calculate the accuracy, precision, and recall accuracy = accuracy_score(y_test, y_pred) precision = precision_score(y_test, y_pred, average=’weighted’) recall = recall_score(y_test, y_pred, average=’weighted’) print(‘Accuracy:’, accuracy) print(‘Precision:’, precision) print(‘Recall:’, recall)
В приведённом выше коде мы сначала используем метод predict() для прогнозирования меток тестового набора. Затем мы вычисляем различные показатели, используя функции accuracy_score(), precision_score()и recall_score()из библиотеки scikit-learn.
VIII. Реальные приложения и тематические исследования
Распознавание изображений имеет множество реальных применений, от обнаружения и отслеживания объектов до распознавания лиц и биометрии . Вот несколько примеров:
A. Обнаружение и отслеживание объектов
Обнаружение и отслеживание объектов используются во многих областях, от наблюдения и безопасности до беспилотных автомобилей. Цель состоит в том, чтобы обнаруживать и отслеживать объекты в изображениях или видеопотоках.
B. Распознавание лиц и биометрия
Распознавание лиц используется в различных приложениях, включая безопасность, наблюдение и биометрию. Цель состоит в том, чтобы идентифицировать людей по их чертам лица.
C. Оптическое распознавание символов (OCR)
OCR используется для распознавания текста на изображениях или отсканированных документах. Эта технология используется в различных приложениях, включая автоматизированную обработку документов и извлечение данных.
D. Сегментация изображения и понимание сцены
Сегментация изображения — это процесс разделения изображения на несколько сегментов, каждый из которых соответствует отдельному объекту или области изображения. Это полезно для таких задач, как распознавание объектов и понимание сцены.
IX. Советы по повышению точности и производительности
Существует несколько методов, которые можно использовать для повышения точности и производительности систем распознавания изображений. Вот несколько примеров:
A. Методы дополнения данных
Расширение данных включает в себя создание новых обучающих данных путем применения преобразований к существующим данным, таких как вращение или переворачивание изображений. Это может помочь увеличить разнообразие обучающих данных и повысить производительность классификатора.
B. Настройка гиперпараметров
Гиперпараметры — это параметры, которые задаются перед обучением классификатора, например, количество признаков для извлечения.
Например, обнаружение и отслеживание объектов используется в автономных транспортных средствах для обнаружения и отслеживания других транспортных средств, пешеходов и препятствий в режиме реального времени. Распознавание лиц и биометрия используются в целях безопасности и идентификации, например, для разблокировки смартфона или проверки личности человека на пограничном контрольно-пропускном пункте. OCR используется для оцифровки текста с изображений и преобразования их в машиночитаемые форматы, а сегментация изображений и понимание сцен используются в робототехнике и компьютерном зрении, чтобы позволить машинам понимать окружающий мир и взаимодействовать с ним.
Существует множество тематических исследований и примеров использования распознавания изображений в промышленности и исследованиях, в том числе:
- Сервис Rekognition от Amazon, который использует глубокое обучение для анализа изображений и видео для различных приложений, включая распознавание лиц, обнаружение объектов и понимание сцены.
- Google Cloud Vision API , который предоставляет ряд возможностей распознавания изображений, включая распознавание меток, распознавание лиц и распознавание текста.
- ImageNet Large Scale Visual Recognition Challenge (ILSVRC) — эталонное соревнование алгоритмов распознавания изображений, которое способствовало прогрессу в этой области.
X. Расширенные темы и дальнейшее изучение
Для тех, кто заинтересован в более глубоком изучении области распознавания изображений , есть много дополнительных тем и методов для изучения, в том числе:
- Глубокое обучение для распознавания изображений с помощью Python и TensorFlow , которое включает в себя создание и обучение нейронных сетей для распознавания изображений.
- Внедрение пользовательских алгоритмов распознавания изображений , таких как обучение без учителя или обучение с подкреплением для обучения алгоритмов.
- Интеграция распознавания изображений в веб-приложения с использованием таких фреймворков, как Flask или Django , для создания интерактивных интерфейсов.
XI. Заключение
В заключение, распознавание изображений — это быстро развивающаяся область со множеством реальных приложений и захватывающими исследовательскими возможностями. Освоив методы и инструменты, описанные в этом пошаговом руководстве, вы сможете приобрести навыки и знания, необходимые для разработки и развёртывания собственных алгоритмов и приложений распознавания изображений.
Статья была взята из этого источника:
объектов и массивов | InfoWorld
Под капотом
Билл Веннерс, JavaWorld |
Посмотрите на байт-коды, которые имеют дело с объектами и массивами в виртуальной машине Java
Добро пожаловать в очередной выпуск Под капотом . В этой колонке основное внимание уделяется технологиям, лежащим в основе Java. Его цель — дать разработчикам представление о механизмах, обеспечивающих выполнение их Java-программ. В статье этого месяца рассматриваются байт-коды, которые имеют дело с объектами и массивами.
Объектно-ориентированная машина
Виртуальная машина Java (JVM) работает с данными в трех формах: объекты, ссылки на объекты и примитивные типы. Объекты находятся в куче со сборкой мусора. Ссылки на объекты и примитивные типы находятся либо в стеке Java как локальные переменные, либо в куче как переменные экземпляра объектов, либо в области методов как переменные класса.
В виртуальной машине Java память выделяется в куче со сборкой мусора только как объекты. Невозможно выделить память для примитивного типа в куче, кроме как как часть объекта. Если вы хотите использовать примитивный тип, где требуется ссылка Object
, вы можете выделить объект-оболочку для типа из пакета java.lang
. Например, существует класс Integer
, который обертывает тип int
объектом. Только ссылки на объекты и примитивные типы могут находиться в стеке Java как локальные переменные. Объекты никогда не могут находиться в стеке Java.
Архитектурное разделение объектов и примитивных типов в JVM отражено в языке программирования Java, в котором объекты не могут быть объявлены как локальные переменные. Только ссылки на объекты могут быть объявлены как таковые. При объявлении ссылка на объект ни на что не ссылается. Только после того, как ссылка была явно инициализирована — либо ссылкой на существующий объект, либо вызовом new
— ссылка ссылается на фактический объект.
В наборе инструкций JVM все объекты создаются и доступны с одним и тем же набором кодов операций, за исключением массивов. В Java массивы являются полноценными объектами и, как и любой другой объект в программе на Java, создаются динамически. Ссылки на массивы можно использовать везде, где есть ссылка на тип 9.0017 Вызывается объект , и любой метод объекта
может быть вызван для массива. Тем не менее, в виртуальной машине Java массивы обрабатываются специальными байт-кодами.
Как и любой другой объект, массивы нельзя объявлять как локальные переменные; только ссылки на массивы могут. Сами объекты-массивы всегда содержат либо массив примитивных типов, либо массив ссылок на объекты. Если вы объявляете массив объектов, вы получаете массив ссылок на объекты. Сами объекты должны быть явно созданы с помощью новый
и присваивается элементам массива.
Коды операций для объектов
Создание новых объектов осуществляется с помощью кода операции
new
. За кодом операции
new
следуют два однобайтовых операнда. Эти два байта объединяются для формирования 16-битного индекса в константном пуле. Постоянный элемент пула по указанному смещению дает информацию о классе нового объекта. JVM создает новый экземпляр объекта в куче и помещает ссылку на новый объект в стек, как показано ниже.
Код операции | Операнд(ы) | 7 0759 90 049 90 0 0003
---|
новый | indexbyte1, indexbyte2 | создает новый объект на куча, помещает ссылку |
В следующей таблице показаны коды операций, которые помещают и получают поля объекта. Эти коды операций, putfield и getfield, работают только с полями, которые являются переменными экземпляра. Доступ к статическим переменным осуществляется с помощью функций putstatic и getstatic, которые будут описаны позже. Инструкции putfield и getfield принимают по два однобайтовых операнда. Операнды объединяются для формирования 16-битного индекса в константном пуле. Элемент постоянного пула по этому индексу содержит информацию о типе, размере и смещении поля. Ссылка на объект берется из стека как в инструкциях putfield, так и в инструкциях getfield. Инструкция putfield берет значение переменной экземпляра из стека, а инструкция getfield помещает полученное значение переменной экземпляра в стек.
Код операции | Операнд(ы) | 9 600768
---|
поле ввода | indexbyte1, indexbyte2 | заданное поле, указано по индексу, от объекта к значению (оба взяты из стека) |
getfield | indexbyte1, indexbyte2 | помещает поле, указанное индексом, объекта (взято из стека) |
Доступ к переменным класса осуществляется через коды операций getstatic и putstatic, как показано в таблице ниже. И getstatic, и putstatic принимают два однобайтовых операнда, которые объединяются JVM для формирования 16-битного беззнакового смещения в константном пуле. Постоянный элемент пула в этом месте предоставляет информацию об одном статическом поле класса. Поскольку нет никакого конкретного объекта, связанного со статическим полем, нет ссылки на объект, используемой ни getstatic, ни putstatic. Инструкция putstatic берет значение для назначения из стека. Инструкция getstatic помещает полученное значение в стек.
Код операции | Операнд(ы) | 9
---|
9
putstatic | indexbyte1, indexbyte2 | заданное поле, указанное по индексу, от объекта к значению (оба взяты из стека) |
getstatic | indexbyte1, indexbyte2 | помещает поле, указанное индексом, объекта (взятого из стека) |
Следующие коды операций проверяют, ссылается ли ссылка на объект в верхней части стека на экземпляр класса или интерфейса, индексированного операндами после кода операции. Инструкция checkcast выдает CheckCastException
, если объект не является экземпляром указанного класса или интерфейса. В противном случае checkcast ничего не делает. Ссылка на объект остается в стеке, и выполнение продолжается со следующей инструкции. Эта инструкция обеспечивает безопасность приведения типов во время выполнения и является частью защиты JVM.
Инструкция instanceof извлекает ссылку на объект из вершины стека и помещает значение true или false. Если объект действительно является экземпляром указанного класса или интерфейса, то значение true помещается в стек, в противном случае в стек помещается значение false. Инструкция instanceof используется для реализации ключевого слова Java instanceof
, которое позволяет программистам проверять, является ли объект экземпляром определенного класса или интерфейса.
Код операции | Операнд(ы) | Описание |
---|
instanceof | indexbyte1, indexbyte2 | Помещает true, если objectref в стеке является instanceof класса по индексу, иначе помещает false |
Коды операций для массивов
Создание новых массивов осуществляется с помощью кодов операций newarray, anewarray и multianewarray. Код операции newarray используется для создания массивов примитивных типов, отличных от ссылок на объекты. Конкретный тип примитива определяется одним однобайтовым операндом, следующим за кодом операции newarray. Инструкция newarray может создавать массивы для byte, short, char, int, long, float, double или boolean.
Инструкция anewarray создает массив ссылок на объекты. Два однобайтовых операнда следуют за кодом операции anewarray и объединяются для формирования 16-битного индекса в константном пуле. Описание класса объекта, для которого создается массив, находится в пуле констант по указанному индексу. Эта инструкция выделяет место для массива ссылок на объекты и инициализирует ссылки нулевым значением.
Инструкция multianewarray используется для размещения многомерных массивов, которые представляют собой просто массивы массивов, и могут быть выделены повторным использованием инструкций anewarray и newarray. Инструкция multianewarray просто сжимает байт-коды, необходимые для создания многомерных массивов, в одну инструкцию. Два однобайтовых операнда следуют за кодом операции multianewarray и объединяются для формирования 16-битного индекса в константном пуле. Описание класса объекта, для которого создается массив, находится в пуле констант по указанному индексу. Сразу за двумя однобайтовыми операндами, формирующими индекс пула констант, следует однобайтовый операнд, указывающий количество измерений в этом многомерном массиве. Размеры для каждого измерения извлекаются из стека. Эта инструкция выделяет место для всех массивов, необходимых для реализации многомерных массивов.
Код операции | Операнд(ы) |
---|
newarray | atype | выталкивает длину, выделяет новый массив примитивных типов типа, указанного atype, помещает объектную ссылку нового массива |
anewarray | indexbyte1, indexbyte2 | извлекает длину, выделяет новый массив объектов класса, указанного indexbyte1 и indexbyte2, помещает объектную ссылку нового массива длины массива , выделяет новый многомерный массив класса, указанного indexbyte1 и indexbyte2, помещает объектную ссылку нового массива |
В следующей таблице показана инструкция, которая выталкивает ссылку на массив из вершины стека и помещает длину этого массива.
Код операции | Операнд(ы) |
---|
длина массива | (нет) | выводит объектную ссылку из массив, помещает длину этого массива |
Следующие коды операций извлекают элемент из массива. Индекс массива и ссылка на массив извлекаются из стека, а значение по указанному индексу указанного массива помещается обратно в стек.
Код операции | Операнд(ы) | 9074
---|
baload | (нет) | индекс популярности и arrayref массива байтов, pushs arrayref[index] |
caload | (none) | извлекает индекс и arrayref массива символов, pushs arrayref9[index]0084 |
saload | (нет) | извлекает индекс и ссылку на массив из массива шорт, помещает ссылку на массив [индекс] 5 9029 |
iaload | (нет) | извлекает индекс и ссылку на массив из массива целых чисел, помещает arrayref[index] |
laload | (нет) | извлекает индекс и массив из массива ref[index]0084 |
faload | (нет) | извлекает индекс и ссылку на массив массива с плавающей запятой, помещает ссылку на массив [индекс] 5 6 9029 |
daload | (нет) | извлекает индекс и ссылку на массив из массива двойных значений, помещает arrayref[index] |
aaload | (нет) | извлекает индекс ссылки из массива и массивы0084 |
В следующей таблице показаны коды операций, которые сохраняют значение в элементе массива. Значение, индекс и ссылка на массив извлекаются из вершины стека.
Код операции | Операнд(ы) | 062
|
---|