Skip to main content
3 of 5
deleted 1 character in body
Cris Luengo
  • 7k
  • 1
  • 15
  • 37

You are obviously on a fantastic quest to understand how to implement image processing operations in all sorts of languages. The tag tells me that you know that you should use an established image processing library as the basis of any serious work.

Here are some comments on your C++ implementation.

image.h

Proper English spelling would be "Developed by Jimmy Hu".

This file includes headers that you don't use. You should only include headers that you actually need.

        Image()
        {
        }

This should be

        Image() = default;

The implementation of at doesn't check bounds. I would suggest adding assert statements for bounds, to catch bugs in debug mode. A release build would then not test bounds.

operator+= should really test that the sizes of the second image match those of the first. You can then simply iterate over the two arrays without worrying about x and y coordinates. If sizes don't match, the operation should fail.

It is not necessary to use this-> to access members. Some people like it, I think it is superfluous.

The standard way to increment in C++ is ++x, not x++. For an int it doesn't make any difference, but for more complex objects it could be very wasteful. ++x increments the variable, then returns its value. x++ makes a copy of the value of the variable, increments the variable, then returns the copy. If you are not using the value of the expression, use the pre-increment to avoid the unnecessary copy.

image_operations.h

You don't need to forward declare class Image. You include its header file, the class is already declared.

auto ratiox = (float)image.getWidth() / (float)width;

Please get used to the C++ way of casting:

auto ratiox = static_cast<float>(image.getWidth()) / static_cast<float>(width);

It is a more obvious cast and makes your code more readable.

Your functions gaussianFigure2D and gaussianFigure2D2 don't need different names. I would argue the library would be easier to use if they had the same name. The compiler will pick the one or the other function depending on the arguments passed.

std::exp is implemented for all three floating-point types. Consequently, normalDistribution1D can be implemented as a template:

    template<typename T>
    T normalDistribution1D(const T x, const T standard_deviation)
    {
        return std::exp(-x * x / (2 * standard_deviation * standard_deviation));
    }

The same is true for normalDistribution2D.

basic_functions.h

Again you have way too many headers included here. The code in this file is not used in your program, as far as I can tell.

base_types.h

You should not be using <cstdbool>. It is deprecated in C++17 and removed in C++20. The other <c...> headers should not be needed either. Use the C++ library, not the C library.

Instead of #define MAX_PATH 256, use constexpr int MAX_PATH = 256. Preprocessor macros are nice to generate code, but they should not be used for things that you can do with native C++ constructs.

Likewise, instead of the C construct typedef unsigned char BYTE, use using BYTE = unsigned char, which is, to me, much more readable.

This is also a C thing:

typedef struct RGB
{
    unsigned char channels[3];
} RGB;

In C++ it is just

struct RGB
{
    unsigned char channels[3];
};
Cris Luengo
  • 7k
  • 1
  • 15
  • 37