Реализация фильтров
This commit is contained in:
parent
24e2cbb354
commit
3fe2a87e35
4 changed files with 109 additions and 58 deletions
86
bmpimage.cpp
86
bmpimage.cpp
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue