Untitled

mail@pastecode.io avatar
unknown
plain_text
3 years ago
2.3 kB
25
Indexable
#include "ppm_image.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <iostream>
#include <string_view>

using namespace std;

int Sum(img_lib::Color c) {
    return to_integer<int>(c.r) + to_integer<int>(c.g) + to_integer<int>(c.b);
}

// реализуйте оператор Собеля
img_lib::Image Sobel(const img_lib::Image& image)
{   
    const int w = image.GetWidth(),
        h = image.GetHeight(),
        ih = h - 1,
        iw = w - 1;
    img_lib::Image im(w, h, img_lib::Color::Black());
    
    for (int y = 0; y < h; ++y) {
        auto line = im.GetLine(y);
        if (y == 0 or y == ih)
            fill(line, line + w, img_lib::Color::Black());
        else
            for (int x = 0; x < w; ++x)
                if (x == 0 or x == iw)
                    line[x] = img_lib::Color::Black();
                else {
                    const int tl = Sum(image.GetPixel(x - 1, y - 1)),
                        tc = Sum(image.GetPixel(x, y - 1)),
                        tr = Sum(image.GetPixel(x + 1, y - 1)),
                        cl = Sum(image.GetPixel(x - 1, y)),
                        cr = Sum(image.GetPixel(x + 1, y)),
                        bl = Sum(image.GetPixel(x - 1, y + 1)),
                        bc = Sum(image.GetPixel(x, y + 1)),
                        br = Sum(image.GetPixel(x + 1, y + 1));
                    int gx = - tl - 2 * tc - tr + bl + 2 * bc + br,
                        gy = - tl - 2 * cl - bl + tr + 2 * cr + br;
                    
                    double r = sqrt(gx * gx + gy * gy);
                    r = clamp(r, 0., 255.);
                    line[x].r = static_cast<byte>(r);
                    line[x].g = static_cast<byte>(r);
                    line[x].b = static_cast<byte>(r);
                }
    }
    return im;
}

int main(int argc, const char** argv) {
    if (argc != 3) {
        cerr << "Usage: "sv << argv[0] << " <input image> <output image>"sv << endl;
        return 1;
    }

    auto image = img_lib::LoadPPM(argv[1]);
    if (!image) {
        cerr << "Error loading image"sv << endl;
        return 2;
    }

    image = Sobel(image);

    if (!img_lib::SavePPM(argv[2], image)) {
        cerr << "Error saving image"sv << endl;
        return 3;
    }

    cout << "Image saved successfully!"sv << endl;
}