Created
July 18, 2017 03:06
-
-
Save sdamashek/a2db2da5a59e74ca51e110b168e4deea to your computer and use it in GitHub Desktop.
Sobel Edge Detection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <initializer_list> | |
#include <vector> | |
#include <iostream> | |
#include <cmath> | |
#include <limits> | |
template <typename T> | |
class Matrix | |
{ | |
public: | |
std::vector<T> m_vec; | |
const int m_rowNum; | |
Matrix(const Matrix& m) : m_rowNum(m.m_rowNum), m_vec(m.m_vec) {}; | |
Matrix(const int m, const int n) : m_vec(m * n, 0), m_rowNum(n) {}; | |
Matrix(const std::initializer_list<std::initializer_list<T>>& il) : m_rowNum(il.size()) | |
{ | |
int row_s = 0; | |
for (const auto& ix : il) { | |
int col_s = 0; | |
for (const auto& iy : ix) { | |
m_vec.push_back(iy); | |
col_s++; | |
} | |
row_s++; | |
} | |
} | |
const int get_rows() const { return m_rowNum; }; | |
const int get_cols() const { return m_vec.size() / m_rowNum; }; | |
T& operator()(const int col, const int row) | |
{ | |
return el(col, row); | |
} | |
const T& operator()(const int col, const int row) const | |
{ | |
return el(col, row); | |
} | |
T& el(const int col, const int row) | |
{ | |
return m_vec[row * get_cols() + col]; | |
} | |
const T& el(const int col, const int row) const | |
{ | |
return m_vec[row * get_cols() + col]; | |
} | |
void el(const int col, const int row, const T val) | |
{ | |
m_vec[row * get_cols() + col] = val; | |
} | |
const Matrix<T> operator+(const Matrix<T>& other) const | |
{ | |
Matrix<T> result = *this; | |
result += other; | |
return result; | |
} | |
Matrix<T>& operator+=(const Matrix<T>& other) | |
{ | |
for (int i = 0; i < m_vec.size(); i++) { | |
m_vec[i] += other.m_vec[i]; | |
} | |
return *this; | |
} | |
template <typename U> | |
const Matrix<T> operator*(const U other) const | |
{ | |
Matrix<T> result = *this; | |
result *= other; | |
return result; | |
} | |
Matrix<T>& operator*=(const Matrix<T>& other) | |
{ | |
for (int i = 0; i < m_vec.size(); i++) { | |
m_vec[i] *= other.m_vec[i]; | |
} | |
return *this; | |
} | |
Matrix<T>& operator*=(const T other) | |
{ | |
for (int i = 0; i < m_vec.size(); i++) { | |
m_vec[i] *= other; | |
} | |
return *this; | |
} | |
const Matrix<T> operator/(const Matrix<T>& other) const | |
{ | |
Matrix<T> result = *this; | |
result /= other; | |
return result; | |
} | |
Matrix<T>& operator/=(const Matrix<T>& other) const | |
{ | |
for (int i = 0; i < m_vec.size(); i++) { | |
m_vec[i] /= other.m_vec[i]; | |
} | |
return *this; | |
} | |
const Matrix<T> operator^(const int val) const | |
{ | |
Matrix<T> result = *this; | |
result ^= val; | |
return result; | |
} | |
Matrix& operator^=(const int val) | |
{ | |
T temp; | |
for (int i = 0; i < m_vec.size(); i++) { | |
temp = m_vec[i]; | |
for (int j = 1; j < val; j++) | |
m_vec[i] *= temp; | |
} | |
return *this; | |
} | |
Matrix& operator=(const T val) | |
{ | |
for (int i = 0; i < m_vec.size(); i++) { | |
m_vec[i] = val; | |
} | |
return *this; | |
} | |
const Matrix<double> sqrt() const | |
{ | |
Matrix<double> result (get_cols(), get_rows()); | |
for (int i = 0; i < m_vec.size(); i++) { | |
result.m_vec[i] = std::sqrt(m_vec[i]); | |
} | |
return result; | |
} | |
const Matrix<int> round() const | |
{ | |
Matrix<int> result (get_cols(), get_rows()); | |
for (int i = 0; i < m_vec.size(); i++) { | |
result.m_vec[i] = static_cast<int>(std::round(m_vec[i])); | |
} | |
return result; | |
} | |
Matrix& threshold(const T val) | |
{ | |
for (int i = 0; i < m_vec.size(); i++) { | |
if (m_vec[i] > val) | |
m_vec[i] = val; | |
} | |
return *this; | |
} | |
void double_threshold(const T separator, const T val1, const T val2) | |
{ | |
for (int i = 0; i < m_vec.size(); i++) { | |
if (m_vec[i] < separator) { | |
m_vec[i] = val1; | |
} | |
else { | |
m_vec[i] = val2; | |
} | |
} | |
} | |
const T max() | |
{ | |
T result = std::numeric_limits<T>::min(); | |
for (int i = 0; i < m_vec.size(); i++) { | |
if (m_vec[i] > result) | |
result = m_vec[i]; | |
} | |
return result; | |
} | |
Matrix& normalize(const T val) | |
{ | |
T max_val = max(); | |
for (int i = 0; i < m_vec.size(); i++) { | |
m_vec[i] *= val / max_val; | |
} | |
return *this; | |
} | |
template <typename U> | |
const Matrix<double> atan2(const Matrix<U>& x) const | |
{ | |
Matrix<double> result (get_cols(), get_rows()); | |
for (int i = 0; i < m_vec.size(); i++) { | |
result.m_vec[i] = std::atan2(m_vec[i], x.m_vec[i]); | |
} | |
return result; | |
} | |
template <typename U> | |
const Matrix<U> cast() | |
{ | |
Matrix<U> result (get_cols(), get_rows()); | |
for (int i = 0; i < m_vec.size(); i++) { | |
result.m_vec[i] = static_cast<U>(m_vec[i]); | |
} | |
return result; | |
} | |
const T sum() const | |
{ | |
T result = 0; | |
for (auto& el : m_vec) { | |
result += el; | |
} | |
return result; | |
} | |
template <typename U> | |
friend std::ostream& operator<<(std::ostream&, const Matrix<U>&); | |
}; | |
template <typename T> | |
std::ostream& operator<<(std::ostream& os, const Matrix<T>& m) { | |
for (int i = 0; i < m.get_rows(); i++) { | |
os << "[ "; | |
for (int j = 0; j < m.get_cols(); j++) { | |
os << m(j, i) << " "; | |
} | |
os << "]" << std::endl; | |
} | |
return os; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment