Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
661da0f
Update README.md
IzmaylovI Apr 4, 2023
c769929
Update README.md
IzmaylovI Apr 4, 2023
a80972c
Update README.md
IzmaylovI Apr 4, 2023
8bda5f7
Create README.md
IzmaylovI Apr 4, 2023
a0a0271
Update README.md
IzmaylovI Apr 4, 2023
89304f1
Update README.md
IzmaylovI Apr 4, 2023
91c14d3
first_request
IzmaylovI Apr 4, 2023
bf4d7aa
Update README.md
IzmaylovI Apr 4, 2023
7f96814
First_correction
IzmaylovI Apr 5, 2023
9d468c2
Merge branch 'main' of https://github.com/IzmaylovI/itlab_2022
IzmaylovI Apr 5, 2023
04b352a
BMP_parsing
IzmaylovI Apr 11, 2023
0172ef7
Corrected_commit
IzmaylovI Apr 12, 2023
d36f8a3
fixed_Function.hpp
IzmaylovI Apr 14, 2023
5e09a7d
Merge branch 'embedded-dev-research:main' into main
IzmaylovI Apr 21, 2023
38e18a8
repos_modules
IzmaylovI Apr 21, 2023
63fe063
RAII-Timer_and_CMakeLists-fixes
IzmaylovI Apr 23, 2023
a69ca2e
Changed_header_file_names_again
IzmaylovI Apr 23, 2023
5fc58d0
add_class_benchmark
IzmaylovI May 4, 2023
dbefac0
add_benchmark_checked_code_style
IzmaylovI May 4, 2023
723d29f
code style
IzmaylovI May 4, 2023
fc65ede
code_style
IzmaylovI May 4, 2023
8b74bdc
code_style
IzmaylovI May 4, 2023
3e92315
code style
IzmaylovI May 4, 2023
bb54430
code_style
IzmaylovI May 4, 2023
8cad4be
code_style
IzmaylovI May 4, 2023
babacdd
code_style
IzmaylovI May 4, 2023
ba0bd4e
code_style
IzmaylovI May 4, 2023
cf6705d
build check
IzmaylovI May 4, 2023
6086e16
build_check
IzmaylovI May 4, 2023
6720760
build_check
IzmaylovI May 4, 2023
a56aed3
build_check
IzmaylovI May 4, 2023
e86263b
build_check
IzmaylovI May 4, 2023
a83ae67
build_check
IzmaylovI May 4, 2023
cb0ecf1
build_check
IzmaylovI May 4, 2023
e9f05dd
build_check
IzmaylovI May 4, 2023
0910467
build_check
IzmaylovI May 4, 2023
aef2fe3
build_check
IzmaylovI May 4, 2023
6ef9ad8
build_check
IzmaylovI May 4, 2023
f8e4fae
build_check
IzmaylovI May 4, 2023
288bb56
build_check
IzmaylovI May 4, 2023
d51ede7
build_check
IzmaylovI May 4, 2023
8ba739b
build_check
IzmaylovI May 4, 2023
0e05920
build_check
IzmaylovI May 4, 2023
d56edb1
build_check
IzmaylovI May 4, 2023
b130c86
build_check
IzmaylovI May 4, 2023
63149a8
build_check
IzmaylovI May 4, 2023
b396aac
build_check
IzmaylovI May 4, 2023
01817e9
build_check
IzmaylovI May 4, 2023
ee22f68
build_check
IzmaylovI May 4, 2023
11999d0
build_check
IzmaylovI May 4, 2023
0295cac
build_check
IzmaylovI May 4, 2023
2a12b24
build_check
IzmaylovI May 4, 2023
451c0d3
build_check
IzmaylovI May 4, 2023
3c34f49
build_check
IzmaylovI May 4, 2023
22fe1b8
class_benchmark_and_code_style
IzmaylovI May 5, 2023
59a3438
code_style
IzmaylovI May 10, 2023
8c2bf2d
code_style
IzmaylovI May 10, 2023
351a1a3
added_option_to_cmake_for_opencv
IzmaylovI May 11, 2023
b73f8f9
resolved_first_conflict
IzmaylovI May 13, 2023
41169e9
filter
IzmaylovI May 26, 2023
2418b60
filter
IzmaylovI May 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ jobs:
path: |
opencv
build_opencv
key: ubuntu-x86-cross-build-opencv
key: ubuntu-x86-cross-build-opencv
55 changes: 40 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,46 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.25.0)

project(computer_vision)

include_directories(./headers)

set(HDR1 headers/Function.hpp)
set(SRC1 sources/Function.cpp)
add_library(func_algo1 ${HDR1} ${SRC1})

find_package(OpenMP)
if(OpenMP_FOUND)
message(STATUS "Link OpenMP")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
include_directories(./generating_data/headers)
include_directories(./algorithms/headers)
include_directories(./tests/headers)
include_directories(./benchmarks/headers)

set(ALGORITHMS_HDR algorithms/headers/function.hpp)
set(ALGORITHMS_SRC algorithms/sources/function.cpp)
add_library(func_algo ${ALGORITHMS_HDR} ${ALGORITHMS_SRC})

set(TIMER_HDR benchmarks/headers/timer.hpp)
set(TIMER_SRC benchmarks/sources/timer.cpp)
add_library(func_timer ${TIMER_HDR} ${TIMER_SRC})

add_executable(computer_vision main.cpp)

#Link OpenMP
option(WITH_OPENCV2 "Build with OpenCV" OFF)
if(WITH_OPENCV2)
find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
message(STATUS "Link OpenCV")
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_compile_definitions(WITH_OPENCV2)
target_link_libraries(computer_vision ${OpenCV_LIBS})
else()
message(STATUS "Not link OpenCV")
endif()
endif()

# Link OpenCV
find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
message(STATUS "Link OpenCV")
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_compile_definitions(WITH_OPENCV2)
target_link_libraries(computer_vision ${OpenCV_LIBS})
else()
message(STATUS "Not link OpenMP")
message(STATUS "Not link OpenCV")
endif()

add_executable(computer_vision main.cpp ./headers/Structer.hpp ./headers/data_render.hpp ./headers/Color.hpp ./headers/BMP.hpp)
target_link_libraries(computer_vision func_algo1)
target_link_libraries(computer_vision func_algo)
target_link_libraries(computer_vision func_timer)

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- Working with Raspberry PI devices in practice.

## Software modules:
### Data rendering
### Data generating
A module for generating data/reading images and storing images. The Image class is independent when reading format images `.bmp` (`OpenCV` library is used for other formats).
### Algorithms
The algorithms module. At the moment, it contains the following matrix multiplication algorithms: classical multiplication,multiplication using OpenMP and Neon_intrinsics
Expand Down
136 changes: 136 additions & 0 deletions algorithms/headers/filter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#include <algorithm>
#include <cmath>

#include "structer.hpp"

int interval(int val, int mmin, int mmax) {
int ans;
if (val < mmin)
ans = mmin;
else if (val > mmax)
ans = mmax;
else
ans = val;

return ans;
}

template <layout Layout>
Image<Layout> Filter(const Image<Layout>& sourceImage);

template <layout Layout>
Color<Layout> SobelX(const Image<Layout>& im, int x, int y);

template <layout Layout>
Color<Layout> SobelY(const Image<Layout>& im, int x, int y);

template <layout Layout>
Image<Layout> Filter(const Image<Layout>& sourceImage) {
Image<Layout> resIm(sourceImage.height, sourceImage.width);

Image<Layout> resImX(sourceImage.height, sourceImage.width);
for (int i = 0; i < resImX.height; i++) {
for (int j = 0; j < resImX.width; j++) {
resImX(i, j) = SobelX(sourceImage, i, j);
}
}

Image<Layout> resImY(sourceImage.height, sourceImage.width);
for (int i = 0; i < resImY.height; i++) {
for (int j = 0; j < resImY.width; j++) {
resImY(i, j) = SobelY(sourceImage, i, j);
}
}

for (int i = 0; i < resIm.height; i++) {
for (int j = 0; j < resIm.width; j++) {
float resultR = sqrt(resImX(i, j).R() * resImX(i, j).R() +
resImY(i, j).R() * resImY(i, j).R());
float resultG = sqrt(resImX(i, j).G() * resImX(i, j).G() +
resImY(i, j).G() * resImY(i, j).G());
float resultB = sqrt(resImX(i, j).B() * resImX(i, j).B() +
resImY(i, j).B() * resImY(i, j).B());
resIm(i, j).R() = interval((unsigned char)resultR, 0, 255);
resIm(i, j).G() = interval((unsigned char)resultG, 0, 255);
resIm(i, j).B() = interval((unsigned char)resultB, 0, 255);
}
}

return resIm;
}

template <layout Layout>
Color<Layout> SobelX(const Image<Layout>& im, int x, int y) {
int radiusX = 1;
int radiusY = 1;

Mtrx<int> kernelX(3, 3);
kernelX(0, 0) = -1;
kernelX(0, 1) = 0;
kernelX(0, 2) = 1;

kernelX(1, 0) = -2;
kernelX(1, 1) = 0;
kernelX(1, 2) = 2;

kernelX(2, 0) = -1;
kernelX(2, 1) = 0;
kernelX(2, 2) = 1;

float resultR = 0;
float resultG = 0;
float resultB = 0;

for (int l = -radiusY; l <= radiusY; l++) {
for (int k = -radiusX; k <= radiusX; k++) {
int idX = interval(x + l, 0, im.height - 1);
int idY = interval(y + k, 0, im.width - 1);
Color<Layout> neighborColor = im(idX, idY);
resultR += neighborColor.R() * kernelX(l + radiusX, k + radiusY);
resultG += neighborColor.G() * kernelX(l + radiusX, k + radiusY);
resultB += neighborColor.B() * kernelX(l + radiusX, k + radiusY);
}
}

return Color<Layout>(interval((unsigned char)resultR, 0, 255),
interval((unsigned char)resultG, 0, 255),
interval((unsigned char)resultB, 0, 255));
}

template <layout Layout>
Color<Layout> SobelY(const Image<Layout>& im, int x, int y) {
int radiusX = 1;
int radiusY = 1;

Mtrx<int> kernelY(3, 3);
kernelY(0, 0) = -1;
kernelY(0, 1) = -2;
kernelY(0, 2) = -1;

kernelY(1, 0) = 0;
kernelY(1, 1) = 0;
kernelY(1, 2) = 0;

kernelY(2, 0) = 1;
kernelY(2, 1) = 2;
kernelY(2, 2) = 1;

float resultR = 0;
float resultG = 0;
float resultB = 0;

for (int l = -radiusY; l <= radiusY; l++) {
for (int k = -radiusX; k <= radiusX; k++) {
int idX = interval(x + l, 0, im.height - 1);
int idY = interval(y + k, 0, im.width - 1);
Color<Layout> neighborColor = im(idX, idY);
resultR += neighborColor.R() * kernelY(l + radiusX, k + radiusY);
resultG += neighborColor.G() * kernelY(l + radiusX, k + radiusY);
resultB += neighborColor.B() * kernelY(l + radiusX, k + radiusY);
}
}

return Color<Layout>(interval((unsigned char)resultR, 0, 255),
interval((unsigned char)resultG, 0, 255),
interval((unsigned char)resultB, 0, 255));
}
6 changes: 3 additions & 3 deletions headers/Function.hpp → algorithms/headers/function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include <arm_neon.h>
#include <omp.h>

#define cllps 3
#define thr 4
#define cllps 1
#define thr 1

template <typename T>
T multiplication_omp(const T& data1, const T& data2, int N, int M, int L) {
Expand All @@ -28,4 +28,4 @@ void matrix_multiply_4x4_neon_float(float32_t* A, float32_t* B, float32_t* C,
void matrix_multiply_2x2_neon_float(float32_t* A, float32_t* B, float32_t* C,
int N, int M, int L);

#endif
#endif // _FUNCTION_
4 changes: 1 addition & 3 deletions sources/Function.cpp → algorithms/sources/function.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "Function.hpp"
#include "function.hpp"

void matrix_multiply_4x4_neon_float(float32_t* A, float32_t* B, float32_t* C,
int N, int M, int L) {
Expand Down Expand Up @@ -59,12 +59,10 @@ void matrix_multiply_4x4_neon_float(float32_t* A, float32_t* B, float32_t* C,
C1 = vfmaq_laneq_f32(C1, B1, A1, 1);
C1 = vfmaq_laneq_f32(C1, B2, A1, 2);
C1 = vfmaq_laneq_f32(C1, B3, A1, 3);

C2 = vfmaq_laneq_f32(C2, B0, A2, 0);
C2 = vfmaq_laneq_f32(C2, B1, A2, 1);
C2 = vfmaq_laneq_f32(C2, B2, A2, 2);
C2 = vfmaq_laneq_f32(C2, B3, A2, 3);

C3 = vfmaq_laneq_f32(C3, B0, A3, 0);
C3 = vfmaq_laneq_f32(C3, B1, A3, 1);
C3 = vfmaq_laneq_f32(C3, B2, A3, 2);
Expand Down
71 changes: 71 additions & 0 deletions benchmarks/headers/benchmark.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef _BENCHMARK_
#define _BENCHMARK_

#include <arm_neon.h>

#include <functional>
#include <iostream>
#include <string>
#include <vector>

#include "timer.hpp"

template <typename Func, typename... Arg>
class Benchmark {
private:
int m_count; // number of iterations of the measurement
std::string m_name; // function benchmark name
std::function<void()> m_func; // pointer to the function to be measured
double exec_time; // arithmetic mean of function execution time (seconds)
public:
Benchmark(Func func, Arg... args);

void setIterations(int count); // sets the number of benchmark iterations
void setName(const std::string& name); // sets the name of the benchmark
void run(); // launch benchmark
void info(); // output of benchmark information
};

template <typename Func, typename... Arg>
Benchmark<Func, Arg...>::Benchmark(Func func, Arg... args)
: m_count(1), m_name("Some function"), exec_time(-1) {
m_func = std::bind(func, args...);
}

template <typename Func, typename... Arg>
void Benchmark<Func, Arg...>::setIterations(int count) {
m_count = count;
}

template <typename Func, typename... Arg>
void Benchmark<Func, Arg...>::setName(const std::string& name) {
m_name = name;
}

template <typename Func, typename... Arg>
void Benchmark<Func, Arg...>::run() {
try {
if (m_name == "Some function") throw(-1);
} catch (int except) {
std::cout << "Set the name of the function under test:"
"<object>.setName(\"Function name\")"
<< std::endl;
}
double total_time = 0;
for (int i = 0; i < m_count; i++) {
Timer t;
m_func();
t.stop();
total_time += t.duration_s();
}
exec_time = total_time / m_count;
}

template <typename Func, typename... Arg>
void Benchmark<Func, Arg...>::info() {
std::cout << " " << m_name << std::endl;
std::cout << "===========================" << std::endl;
std::cout << "Timer: " << exec_time << " seconds" << std::endl;
}

#endif // _BENCHMARK_
26 changes: 26 additions & 0 deletions benchmarks/headers/timer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _TIMER_
#define _TIMER_

#include <omp.h>

#include <chrono>
#include <iostream>

class Timer {
private:
bool strt; // timer start flag
bool stp; // timeк stop flag
std::chrono::time_point<std::chrono::high_resolution_clock> m_StartPoint{};
std::chrono::duration<double> duration;

public:
Timer(); // сonstructor: initializes the timer duration to zero microseconds
~Timer(); // returns a time measurement resource
void start(); // starts the timer
void stop(); // stops time

double duration_s(); // Timer measurement duration in seconds
double duration_ms(); // Timer measurement duration in milliseconds
};

#endif // _TIMER_
33 changes: 33 additions & 0 deletions benchmarks/sources/timer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "timer.hpp"

Timer::Timer()
: strt(true), stp(false), duration(std::chrono::microseconds{0}) {
start();
}

Timer::~Timer() {
if (strt && !stp) stop();
}

void Timer::start() {
strt = true;
stp = false;
m_StartPoint = std::chrono::high_resolution_clock::now();
} /*-------------------------------------------------------------------------*/

void Timer::stop() {
stp = true;
std::chrono::time_point<std::chrono::high_resolution_clock> m_EndPoint =
std::chrono::high_resolution_clock::now();
duration = m_EndPoint - m_StartPoint;
} /*-------------------------------------------------------------------------*/

double Timer::duration_s() {
if (!stp) std::cout << "Warning!!! The timer did not stop" << std::endl;
return duration.count();
} /*-------------------------------------------------------------------------*/

double Timer::duration_ms() {
if (!stp) std::cout << "Warning!!! The timer did not stop" << std::endl;
return duration.count() * 1000.0;
} /*-------------------------------------------------------------------------*/
2 changes: 1 addition & 1 deletion headers/BMP.hpp → generating_data/headers/bmp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ void check_color_header(BMPColorHeader& bmp_color_header) {
}
}
#pragma pack(pop)
#endif
#endif // __BMP__
2 changes: 1 addition & 1 deletion headers/Color.hpp → generating_data/headers/color.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,4 @@ std::ostream& operator<<(std::ostream& out, const Color<layout::bgr>& color_m) {
out << (int)color_m.B() << ',' << (int)color_m.G() << ',' << (int)color_m.R();
return out;
}
#endif
#endif // _COLOR_
Loading