Завершено
5
22.03.2021, 13:59
19.04.2021, 12:04
Реализовать класс Image
для работы с изображениями c применением техники
reference counting.
Класс представляет собой многоканальный двумерный массив из unsigned char
для хранения пикселей изображения.
Цифровые изображения состоят из пикселей, а пиксели состоят из комбинаций основных цветов. Набор основных цветов называются каналами. Например, RGB изображения состоят из 3-х каналов: R (red), G (green), B (blue), а изображения в градациях серого являются одноканальными.
Реализовать основной класс Image
и вспомогательный класс Range
.
public
и protected
методы классов фиксированы,
кроме спецификаторов.
Т.е. нельзя менять названия методов, а также типы и количество аргументов.
НО в этих методах отсутствуют спецификаторы const
и static
,
которые были удалены намеренно. Их необходимо вернуть на место.
private
поля и private
методы можно добавлять в класс Image
.
Класс Range
cамодостаточен и не нуждается в дополнительных полях и методах.
//Range.hpp
class Range
{
int _start, _end;
public:
Range();
Range(int _start, int _end);
int size();
bool empty();
int start();
int end();
Range all();
};
Класс Range
используется для указания полуоткрытого
диапазона значений строк или столбцов. Т.е [a,b) = {a <= x < b}.
Range()
-- конструктор по умолчанию. Инициализация нулями.
Range(int _start, int _end)
-- конструктор
с заданием полуоткрытого диапазона [_start, _end)
.
Если _start < 0 || _start >= _end
, то поля инициализируются нулями.
int size()
-- возвращает
размер (длину) диапазона.
bool empty()
-- возвращает true
или false
в зависимости от того, является диапазон
пустым или нет.
int start()
-- возращает значение _start
.
int end()
-- возращает значение _end
.
Range all()
-- возвращает специальную переменную Range
, которая означает
"весь диапазон". Данный метод не зависит от значений полей start
и end
.
int _start
- приватное поле класса, содержащее значение инклюзивной левой границы диапазона.
int _end
- приватное поле класса, содержащее значение исключительной правой границы диапазона.
//Image.hpp
#include "Range.h"
class Image {
public:
Image();
Image(int rows, int cols, int channels);
Image(int rows, int cols, int channels, unsigned char* data);
Image(const Image& image);
Image(const Image& image, const Range& rowRange, const Range& colRange);
virtual ~Image();
Image& operator=(const Image& image);
Image operator()(const Range& rowRange, const Range& colRange);
Image clone();
void copyTo(Image& image);
void create(int rows, int cols, int channels);
bool empty();
void release();
Image col(int x);
Image colRange(const Range& range);
Image row(int y);
Image rowRange(const Range& range);
const unsigned char* data() const;
unsigned char* data();
int rows();
int cols();
int total();
int channels();
unsigned char& at(int index);
const unsigned char& at(int index) const;
Image zeros(int rows, int cols, int channels);
Image values(int rows, int cols, int channels, unsigned char value);
size_t countRef();
};
Image()
-- конструктор по умолчанию.Image(int rows, int cols, int channels)
-- конструктор с заданием
количества строк rows
, столбцов cols
и каналов channels
.Image(int rows, int cols, int channels, unsigned char* data)
--
конструктор, который отличается от вышеуказанного дополнительным параметром,
указателем на пользовательские данные data
.
Данный конструктор не выделяет новую память и не копирует данные,
а просто использует переданный указатель на данные (пиксели).
Эта операция очень эффективна и может использоваться для обработки внешних данных.
Внешние данные не освобождаются в деструкторе, поскольку за них ответственен пользователь.Image(const Image& image)
-- конструктор копий.
Данный конструктор не выделяет новую память, а применяет технику reference counting.
Сложность создания копии объекта O(1).Image(const Image& image, const Range& rowRange, const Range& colRange)
--
конструктор копий, который отличается от вышеуказанного дополнительными параметрами
rowRange
и colRange
, которые задают прямоугольную область.
Дополнительные параметры позволяют создать копию не всего изображения,
а только части изображения. Данный конструктор также не выделяет новую память,
а применяет технику reference counting. Сложность создания копии объекта O(1).
Если range
выходит за область изображения, то он обрезается до границы изображения.
~Image()
-- деструктор.
operator=(const Image& image)
-- оператор присваивания. В некотором роде
похож на конструктор. Т.е. не выделяет новую память, а применяет технику reference counting.
Сложность данной операции O(1).
operator()(const Range& rowRange, const Range& colRange)
--
выделяет прямоугольное под-изображение. Данный оператор возвращает то изображение, которое
находится в заданной (с помощью параметров rowRange
и colRange
) области.
Сложность операции O(1), копирования и выделения новой памяти не требуется. Используется
техника reference counting. Если range
выходит за область изображения, то он обрезается до границы изображения.
clone()
-- создает полную копию изображения. Выделяет новую память и производит копирование пикселей.
Сложность операции O(n), где n - количество пикселей.
copyTo(Image& image)
-- метод производит полное копирование изображения в объект
image
. Сложность операции O(n).
create(int rows, int cols, int channels)
-- метод задает новые размеры
текущего изображения.
empty()
-- возвращает true
или false
в зависимости от того, является изображение пустым или нет.
release()
-- декрементирует счетчик ссылок и в случае необходимости освобождает ресурсы (память).
col(int x)
-- возвращает новое изображение, которое содержит один столбец по индексу x
.
Сложность операции O(1). Память не выделяется, используется reference counting.
Если x
превышает ширину изображения, то метод должен вернуть
пустое изображение.
colRange(const Range& range)
-- возвращает новое изображение, которое содержит
диапазон столбцов range
.
Сложность операции O(1). Память не выделяется, используется reference counting.
Если range
выходит за область изображения, то он обрезается до границы изображения.
row(int y)
-- аналог метода col(int x)
для строк.
rowRange(const Range& range)
-- аналог метода
colRange(const Range& range)
для строк.
data() const
-- возвращет указатель на константные данные (пиксели).
data()
-- возвращет указатель на данные (пиксели).
rows()
-- возвращает общее количество строк в изображении.
cols()
-- возвращает общее количество столбцов в изображении (без учета каналов).
total()
-- возвращает общее количество пикселей в изображении.
channels()
-- возвращает количество каналов в пикселе.
at(int index)
-- возвращает ссылку на компоненту пикселя изображения
(не на весь пиксель, а на часть) по индексу.
at(int index)
-- возвращает константную ссылку на компоненту пикселя изображения
(не на весь пиксель, а на часть) по индексу.
zeros(int rows, int cols, int channels)
-- создает новое изображение, которое
инициализируется нулями.
values(int rows, int cols, int channels)
-- создает новое изображение, которое
инициализируется значением value
.
countRef()
-- возвращает текущее количество ссылок на изображение. Т.е.
количество объектов, которые ссылаются на данное изображение. Этот метод нужен для
unit test'ов.
public
методам, классов Range
и Image
,
необходимо добавить спецификаторы static
и const
.
Но только в те места, где это необходимо.public
и protected
методы классов фиксированы, кроме спецификаторов.
Т.е. нельзя менять названия методов, а также типы и количество аргументов.Image.hpp, Image.cpp, Range.hpp, Range.cpp
.