Реализация фильтров

This commit is contained in:
Евгений Титаренко 2024-04-19 21:17:03 +03:00
parent 24e2cbb354
commit 3fe2a87e35
4 changed files with 109 additions and 58 deletions

View file

@ -1,4 +1,6 @@
#include <cmath>
#include <memory>
#include <algorithm>
#include "bmpimage.h"
BMPImage::BMPImage(const BitmapFileHeader &fileHeader, const BITMAPINFOHEADER &infoHeader, const PixelArray &pixelArray)
@ -83,6 +85,7 @@ BMPImage BMPImage::appendRight(BMPImage &img) {
uint32_t newWidth = this->infoHeader.BitmapWidth + img.width();
// Pixel **newPixelArray;
PixelArray newPixelArray(newWidth, newHeight);
// std::shared_ptr<PixelArray> newPixelArray = std::make_shared<PixelArray>(newWidth, newHeight);
// newPixelArray = new Pixel *[newHeight];
for (int i = 0; i < this->infoHeader.BitmapHeight; ++i) {
// newPixelArray[i] = new Pixel[newWidth];
@ -105,6 +108,32 @@ BMPImage BMPImage::overlay(BMPImage &img, uint32_t pos_x, uint32_t pos_y) {
return {pixels};
}
BMPImage BMPImage::applyFilter(const std::function<uint8_t(std::array<int, 9> &)> &filter) {
auto origPixels = this->pixels_copy();
PixelArray pixels(this->width(), this->height());
for (int y = 1; y < this->height() - 1; ++y) {
for (int x = 1; x < this->width() - 1; ++x) {
auto p1 = origPixels(y - 1, x - 1);
auto p2 = origPixels(y - 1, x);
auto p3 = origPixels(y - 1, x + 1);
auto p4 = origPixels(y, x - 1);
auto p5 = origPixels(y, x);
auto p6 = origPixels(y, x + 1);
auto p7 = origPixels(y + 1, x - 1);
auto p8 = origPixels(y + 1, x);
auto p9 = origPixels(y + 1, x + 1);
std::array<int, 9> red_channel = {p1.r, p2.r, p3.r, p4.r, p5.r, p6.r, p7.r, p8.r, p9.r};
std::array<int, 9> green_channel = {p1.g, p2.g, p3.g, p4.g, p5.g, p6.g, p7.g, p8.g, p9.g};
std::array<int, 9> blue_channel = {p1.b, p2.b, p3.b, p4.b, p5.b, p6.b, p7.b, p8.b, p9.b};
auto r = filter(red_channel);
auto g = filter(green_channel);
auto b = filter(blue_channel);
pixels(y, x) = {r, g, b};
}
}
return {pixels};
}
BMPImage readBMPImage(const std::string &filename) {
BitmapFileHeader bitmapFileHeader;
@ -405,30 +434,39 @@ BMPImage upscale2x_ver2(BMPImage &img) {
return {newPixelArray};
}
BMPImage filter(BMPImage &img, int mask[9], uint8_t modifier) {
auto origPixels = img.pixels_copy();
PixelArray pixels(img.width(), img.height());
for (int y = 1; y < img.height() - 1; ++y) {
for (int x = 1; x < img.width() - 1; ++x) {
auto p1 = origPixels(y - 1, x - 1);
auto p2 = origPixels(y - 1, x);
auto p3 = origPixels(y - 1, x + 1);
auto p4 = origPixels(y, x - 1);
auto p5 = origPixels(y, x);
auto p6 = origPixels(y, x + 1);
auto p7 = origPixels(y + 1, x - 1);
auto p8 = origPixels(y + 1, x);
auto p9 = origPixels(y + 1, x + 1);
auto r = p1.r * mask[0] + p2.r * mask[1] + p3.r * mask[2] + p4.r * mask[3] + p5.r * mask[4] +
p6.r * mask[5] + p7.r * mask[6] + p8.r * mask[7] + p9.r * mask[8];
auto g = p1.g * mask[0] + p2.g * mask[1] + p3.g * mask[2] + p4.g * mask[3] + p5.g * mask[4] +
p6.g * mask[5] + p7.g * mask[6] + p8.g * mask[7] + p9.g * mask[8];
auto b = p1.b * mask[0] + p2.b * mask[1] + p3.b * mask[2] + p4.b * mask[3] + p5.b * mask[4] +
p6.b * mask[5] + p7.b * mask[6] + p8.b * mask[7] + p9.b * mask[8];
pixels(y, x) = {ui8_clamp(r / modifier), ui8_clamp(g / modifier), ui8_clamp(b / modifier)};
}
}
return {pixels};
uint8_t medianFilter(std::array<int, 9> &pixels) {
std::sort(pixels.begin(), pixels.end());
return ui8_clamp(pixels[5]);
}
uint8_t averageFilter(std::array<int, 9> &pixels) {
return ui8_clamp((pixels[0] * AVERAGE_MASK[0] + pixels[1] * AVERAGE_MASK[1] + pixels[2] * AVERAGE_MASK[2] +
pixels[3] * AVERAGE_MASK[3] + pixels[4] * AVERAGE_MASK[4] + pixels[5] * AVERAGE_MASK[5] +
pixels[6] * AVERAGE_MASK[6] + pixels[7] * AVERAGE_MASK[7] + pixels[8] * AVERAGE_MASK[8]) / 9);
}
uint8_t prewittDXFilter(std::array<int, 9> &pixels) {
return ui8_clamp(pixels[0] * PREWITT_MASK_DX[0] + pixels[1] * PREWITT_MASK_DX[1] + pixels[2] * PREWITT_MASK_DX[2] +
pixels[3] * PREWITT_MASK_DX[3] + pixels[4] * PREWITT_MASK_DX[4] + pixels[5] * PREWITT_MASK_DX[5] +
pixels[6] * PREWITT_MASK_DX[6] + pixels[7] * PREWITT_MASK_DX[7] + pixels[8] * PREWITT_MASK_DX[8]);
}
uint8_t prewittDYFilter(std::array<int, 9> &pixels) {
return ui8_clamp(pixels[0] * PREWITT_MASK_DY[0] + pixels[1] * PREWITT_MASK_DY[1] + pixels[2] * PREWITT_MASK_DY[2] +
pixels[3] * PREWITT_MASK_DY[3] + pixels[4] * PREWITT_MASK_DY[4] + pixels[5] * PREWITT_MASK_DY[5] +
pixels[6] * PREWITT_MASK_DY[6] + pixels[7] * PREWITT_MASK_DY[7] + pixels[8] * PREWITT_MASK_DY[8]);
}
uint8_t sobelDXFilter(std::array<int, 9> &pixels) {
return ui8_clamp(pixels[0] * SOBEL_MASK_DX[0] + pixels[1] * SOBEL_MASK_DX[1] + pixels[2] * SOBEL_MASK_DX[2] +
pixels[3] * SOBEL_MASK_DX[3] + pixels[4] * SOBEL_MASK_DX[4] + pixels[5] * SOBEL_MASK_DX[5] +
pixels[6] * SOBEL_MASK_DX[6] + pixels[7] * SOBEL_MASK_DX[7] + pixels[8] * SOBEL_MASK_DX[8]);
}
uint8_t sobelDYFilter(std::array<int, 9> &pixels) {
return ui8_clamp(pixels[0] * SOBEL_MASK_DY[0] + pixels[1] * SOBEL_MASK_DY[1] + pixels[2] * SOBEL_MASK_DY[2] +
pixels[3] * SOBEL_MASK_DY[3] + pixels[4] * SOBEL_MASK_DY[4] + pixels[5] * SOBEL_MASK_DY[5] +
pixels[6] * SOBEL_MASK_DY[6] + pixels[7] * SOBEL_MASK_DY[7] + pixels[8] * SOBEL_MASK_DY[8]);
}
PixelArray::PixelArray(uint32_t width, uint32_t height) {