Skip to content

Instantly share code, notes, and snippets.

@kinchungwong
Created October 13, 2016 10:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kinchungwong/8df010d1358318effac5269c50bf4308 to your computer and use it in GitHub Desktop.
Save kinchungwong/8df010d1358318effac5269c50bf4308 to your computer and use it in GitHub Desktop.
Helper functions for reading and writing untyped OpenCV matrix elements (cv::Mat without pixel type) using cv::Scalar as values
template <typename T>
struct IsOpenCvVec
: std::false_type
{
};
template <typename T, int CN>
struct IsOpenCvVec<cv::Vec<T, CN>>
: std::true_type
{
};
template <typename T, bool isVec = IsOpenCvVec<T>::value>
class PixelToScalarFunc;
template <typename T>
class PixelToScalarFunc<T, false>
{
private:
T m_value;
public:
PixelToScalarFunc(const T& value)
: m_value(value)
{
}
operator cv::Scalar() const
{
return cv::Scalar(m_value);
}
};
template <typename T, int CN>
class PixelToScalarFunc<cv::Vec<T, CN>, true>
{
private:
cv::Vec<T, CN> m_value;
public:
PixelToScalarFunc(const cv::Vec<T, CN>& value)
: m_value(value)
{
}
operator cv::Scalar() const
{
cv::Scalar scalar;
for (int k = 0; ((k < CN) && (k < 4)); ++k)
{
scalar[k] = m_value[k];
}
return scalar;
}
};
template <typename T, bool isVec = IsOpenCvVec<T>::value>
class ScalarToPixelFunc;
template <typename T>
class ScalarToPixelFunc<T, false>
{
private:
cv::Scalar m_scalar;
public:
ScalarToPixelFunc(const cv::Scalar& scalar)
: m_scalar(scalar)
{
}
operator T() const
{
return cv::saturate_cast<T>(m_scalar[0]);
}
};
template <typename T, int CN>
class ScalarToPixelFunc<cv::Vec<T, CN>, true>
{
private:
cv::Scalar m_scalar;
public:
ScalarToPixelFunc(const cv::Scalar& scalar)
: m_scalar(scalar)
{
}
operator cv::Vec<T, CN>() const
{
cv::Vec<T, CN> result;
for (int k = 0; ((k < CN) && (k < 4)); ++k)
{
result[k] = cv::saturate_cast<T>(m_scalar[k]);
}
return result;
}
};
template <typename PixelType>
cv::Scalar PixelGetterImpl(const cv::Mat& mat, int row, int col)
{
return PixelToScalarFunc<PixelType>(mat.at<PixelType>(row, col));
}
template <typename PixelType>
void PixelSetterImpl(cv::Mat& mat, int row, int col, const cv::Scalar& scalar)
{
mat.at<PixelType>(row, col) = ScalarToPixelFunc<PixelType>(scalar);
}
typedef cv::Scalar(*PixelGetterPtr)(const cv::Mat& mat, int row, int col);
typedef void(*PixelSetterPtr)(cv::Mat& mat, int row, int col, const cv::Scalar& scalar);
PixelGetterPtr ResolvePixelGetter(int matrixType)
{
static const char* methodName = "ResolvePixelGetter(matrixType)";
switch (matrixType)
{
case CV_8UC1:
return &PixelGetterImpl<uchar>;
case CV_8UC3:
return &PixelGetterImpl<cv::Vec3b>;
default:
throw std::exception(methodName);
}
}
PixelSetterPtr ResolvePixelSetter(int matrixType)
{
static const char* methodName = "ResolvePixelSetter(matrixType)";
switch (matrixType)
{
case CV_8UC1:
return &PixelSetterImpl<uchar>;
case CV_8UC3:
return &PixelSetterImpl<cv::Vec3b>;
default:
throw std::exception(methodName);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment