Skip to content
27 changes: 15 additions & 12 deletions src/OpenCV_ImagesSupport.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,36 @@
# Use * pointer indexing instead of the "at" method implemented in pixset

function convertToMat(image)
img = Images.separate(image);
cd = Images.colordim(img);
img = permuteddimsview(channelview(image), (2,3,1))
cd = Base.size(channelview(image))[1] > 3 ? 1 : 3
_rows = Base.size(image, 1)
_cols = Base.size(image, 2)

if (typeof(img[1,1,1].i) == UInt8)
if (cd < 3); mat = Mat(Base.size(img,2), Base.size(img,1), CV_8UC1); end
if (cd == 3); mat = Mat(Base.size(img,2), Base.size(img,1), CV_8UC3); end
if (cd < 3); mat = Mat(_rows, _cols, CV_8UC1); end
if (cd == 3); mat = Mat(_rows, _cols, CV_8UC3); end
elseif (typeof(img[1,1,1].i) == Float32)
if (cd < 3); mat = Mat(Base.size(img,2), Base.size(img,1), CV_32FC1); end
if (cd == 3); mat = Mat(Base.size(img,2), Base.size(img,1), CV_32FC3); end
if (cd < 3); mat = Mat(_rows, _cols, CV_32FC1); end
if (cd == 3); mat = Mat(_rows, _cols, CV_32FC3); end
elseif (typeof(img[1,1,1].i) == Float64)
if (cd < 3); mat = Mat(Base.size(img,2), Base.size(img,1), CV_64FC1); end
if (cd == 3); mat = Mat(Base.size(img,2), Base.size(img,1), CV_64FC3); end
if (cd < 3); mat = Mat(_rows, _cols, CV_64FC1); end
if (cd == 3); mat = Mat(_rows, _cols, CV_64FC3); end
else
throw(ArgumentError("Pixel format not supported!"))
end

if (cd < 3) # grayscale or binary
for j = 1:Base.size(img,2) # index row first (Mat is row-major order)
for k =1:Base.size(img,1) # index column second
for j = 1:_rows # index row first (Mat is row-major order)
for k =1:_cols # index column second
# slow algorithm - will try to use pointer method (C++)!
pixset(mat, k, j, float(img[k,j,1].i))
end
end
end

if (cd == 3) # color (RGB) image
for j = 1:Base.size(img,2) # index row first (Mat is row-major order)
for k =1:Base.size(img,1) # index column second
for j = 1:_rows # index row first (Mat is row-major order)
for k =1:_cols # index column second
colorvec = tostdvec([float(img[k,j,1].i),float(img[k,j,2].i),float(img[k,j,3].i)])
pixset(mat, k-1, j-1, colorvec) # -1 to have 0-indexing per C++
end
Expand Down
248 changes: 70 additions & 178 deletions src/OpenCV_Mat.jl
Original file line number Diff line number Diff line change
@@ -1,212 +1,107 @@

# Get and set functions for access of pixel values in Mat image arrays
cxx"""
int at_u(cv::Mat &img, int row, int col)
{
return(static_cast<int>(img.at<uchar>(row,col)));
}

void at_u(cv::Mat &img, int row, int col, double val)
{
uchar value = static_cast<uchar>(val);
img.at<uchar>(row,col) = value;
}

int at_s(cv::Mat &img, int row, int col)
{
return(static_cast<int>(img.at<short>(row,col)));
}

void at_s(cv::Mat &img, int row, int col, double val)
{
short value = static_cast<short>(val);
img.at<short>(row,col) = value;
}

int at_us(cv::Mat &img, int row, int col)
{
return(static_cast<int>(img.at<unsigned short>(row,col)));
}

void at_us(cv::Mat &img, int row, int col, double val)
{
unsigned short value = static_cast<unsigned short>(val);
img.at<unsigned short>(row,col) = value;
}

float at_f(cv::Mat &img, int row, int col)
{
return(static_cast<float>(img.at<float>(row,col)));
}

void at_f(cv::Mat &img, int row, int col, double val)
{
float value = static_cast<float>(val);
img.at<float>(row,col) = value;
}

double at_d(cv::Mat &img, int row, int col)
{
return(static_cast<int>(img.at<double>(row,col)));
}

void at_d(cv::Mat &img, int row, int col, double val)
{
img.at<double>(row,col) = val;
}

std::vector<char> at_vc(cv::Mat &img, int row, int col)
{
std::vector<char>vec(3);
for (int i = 0; i < 3; i++) { vec[i]= img.at<cv::Vec<char,3>>(row,col)[i]; }; return vec;
}

void at_vc(cv::Mat& img, int row, int col, std::vector<double> vec)
{
for (int i = 0; i < 3; i++) { img.at<cv::Vec<char,3>>(row,col)[i] = static_cast<char>(vec[i]); };
}

std::vector<uchar> at_v3b(cv::Mat &img, int row, int col)
{
std::vector<uchar>vec(3);
for (int i = 0; i < 3; i++) { vec[i]= img.at<cv::Vec3b>(row,col)[i]; }; return vec;
}

void at_v3b(cv::Mat &img, int row, int col, std::vector<double> vec)
{
for (int i = 0; i < 3; i++) {img.at<cv::Vec3b>(row,col)[i] = static_cast<uchar>(vec[i]); };
}

std::vector<short> at_v3s(cv::Mat &img, int row, int col)
{
std::vector<short>vec(3);
for (int i = 0; i < 3; i++) { vec[i]= img.at<cv::Vec3s>(row,col)[i]; }; return vec;
}

void at_v3s(cv::Mat &img, int row, int col, std::vector<double> vec)
{
for (int i = 0; i < 3; i++) { img.at<cv::Vec3s>(row,col)[i] = static_cast<short>(vec[i]); };
}

std::vector<unsigned short> at_v3us(cv::Mat &img, int row, int col)
{
std::vector<unsigned short>vec(3);
for (int i = 0; i < 3; i++) { vec[i]= img.at<cv::Vec<unsigned short,3>>(row,col)[i]; }; return vec;
}

void at_v3us(cv::Mat &img, int row, int col, std::vector<double> vec)
{
for (int i = 0; i < 3; i++) { img.at<cv::Vec<unsigned short,3>>(row,col)[i] = static_cast<unsigned short>(vec[i]); };
}

std::vector<int> at_v3i(cv::Mat &img, int row, int col)
{
std::vector<int>vec(3);
for (int i = 0; i < 3; i++) { vec[i]= img.at<cv::Vec<unsigned short,3>>(row,col)[i]; }; return vec;
}

void at_v3i(cv::Mat &img, int row, int col,std::vector<double> vec)
cxx"""
// Grayscale and binary images
template <typename T>
inline T ptr_val(cv::Mat &img, int row, int col)
{
for (int i = 0; i < 3; i++) { img.at<cv::Vec<unsigned short,3>>(row,col)[i] = static_cast<int>(vec[i]); };
return(static_cast<int>(img.at<T>(row, col)));
}

std::vector<float> at_v3f(cv::Mat &img, int row, int col)
template <typename T>
inline void ptr_val(cv::Mat &img, int row, int col, double val)
{
std::vector<float>vec(3);
for (int i = 0; i < 3; i++) { vec[i]= img.at<cv::Vec3f>(row,col)[i]; }; return vec;
T value = static_cast<T>(val);
img.at<T>(row, col) = value;
}

void at_v3f(cv::Mat &img, int row, int col, std::vector<double> vec)
// RGB images
template <typename T>
inline std::vector<T> ptr_val3(cv::Mat &img, int row, int col)
{
for (int i = 0; i < 3; i++) { img.at<cv::Vec3f>(row,col)[i] = static_cast<float>(vec[i]); };
std::vector<T>vec(3);
for(int i = 0; i < 3; ++i)
{
vec[i] = img.at<cv::Vec<T, 3>>(row, col)[i];
}
return vec;
}

std::vector<double> at_v3d(cv::Mat &img, int row, int col)
template <typename T>
inline void ptr_val3(cv::Mat &img, int row, int col, std::vector<double> vec)
{
std::vector<double>vec(3);
for (int i = 0; i < 3; i++) { vec[i]= img.at<cv::Vec3d>(row,col)[i]; }; return vec;
for(int i = 0; i < 3; ++i)
{
img.at<cv::Vec<T, 3>>(row, col)[i] = static_cast<T>(vec[i]);
}
}

void at_v3d(cv::Mat &img, int row, int col, std::vector<double> vec)
{
for (int i = 0; i < 3; i++) { img.at<cv::Vec3d>(row,col)[i] = vec[i]; };
}
"""

function pixget(img, row::Int, col::Int)
(row < 0 || col < 0 || row > rows(img) || col > cols(img)) ? throw(BoundsError()) : nothing

# Grayscale and binary images (returns int)
(row < 0 || col < 0 || row > rows(img) || col > cols(img)) ? throw(BoundsError()) : nothingcpp_templates
# Grayscale and binary images
if (cvtypeval(img) == CV_8UC1)
val = @cxx at_u(img, row, col);
#println(int(val)); return (val)
val = @cxx ptr_val<unsigned char>(img, row, col);
elseif (cvtypeval(img) == CV_16SC1)
val = @cxx at_s(img, row, col);
println(Int(val)); return (val)
val = @cxx ptr_val<short>(img, row, col);
elseif (cvtypeval(img) == CV_32SC1)
val = @cxx at_us(img, row, col);
println(Int(val)); return (val)
val = @cxx ptr_val<unsigned short>(img, row, col);
elseif (cvtypeval(img) == CV_32FC1)
val = @cxx at_f(img, row, col);
println(val); return (val)
val = @cxx ptr_val<float>(img, row, col);
elseif (cvtypeval(img) == CV_64FC1)
val = @cxx at_d(img, row, col);
println(val); return (val)
# RGB images (returns vec with original types)
val = @cxx ptr_val<double>(img, row, col);
# RGB images
elseif (cvtypeval(img) == CV_8SC3)
vec = @cxx at_vc(img, row, col);
println([Int(at(vec, 0)), Int(at(vec, 1)),Int(at(vec, 2))]); return (vec)
vec = @cxx ptr_val3<char>(img, row, col);
elseif (cvtypeval(img) == CV_8UC3)
vec = @cxx at_v3b(img, row, col);
println([Int(at(vec, 0)), Int(at(vec, 1)),Int(at(vec, 2))]); return (vec)
vec = @cxx ptr_val3<unsigned char>(img, row, col);
elseif (cvtypeval(img) == CV_16SC3)
vec = @cxx at_v3s(img, row, col);
println([Int(at(vec, 0)), Int(at(vec, 1)),Int(at(vec, 2))]); return (vec)
vec = @cxx ptr_val3<short>(img, row, col);
elseif (cvtypeval(img) == CV_16UC3)
vec = @cxx at_v3us(img, row, col);
println([Int(at(vec, 0)), Int(at(vec, 1)),Int(at(vec, 2))]); return (vec)
vec = @cxx ptr_val3<unsigned short>(img, row, col);
elseif (cvtypeval(img) == CV_32SC3)
vec = @cxx at_v3i(img, row, col);
println([Int(at(vec, 0)), Int(at(vec, 1)),Int(at(vec, 2))]); return (vec)
vec = @cxx ptr_val3<int>(img, row, col);
elseif (cvtypeval(img) == CV_32FC3)
vec = @cxx at_v3f(img, row, col);
println([float(at(vec, 0)), float(at(vec, 1)),float(at(vec, 2))]); return (vec)
vec = @cxx ptr_val3<float>(img, row, col);
elseif (cvtypeval(img) == CV_64FC3)
vec = @cxx at_v3d(img, row, col);
println([at(vec, 0), at(vec, 1),at(vec, 2)]); return (vec)
vec = @cxx ptr_val3<double>(img, row, col);
else throw(ArgumentError("Image format not recognized!"))
end
end


function pixset(img, row::Int, col::Int, value)
(row < 0 || col < 0 || row > rows(img) || col > cols(img)) ? throw(BoundsError()) : nothing
# Grayscale and binary images (value:: double)

# Grayscale and binary images
if (cvtypeval(img) == CV_8UC1)
@cxx at_u(img, row, col, value);
@cxx ptr_val<unsigned char>(img, row, col, value);
elseif (cvtypeval(img) == CV_16SC1)
@cxx at_s(img, row, col, value);
@cxx ptr_val<short>(img, row, col, value);
elseif (cvtypeval(img) == CV_32SC1)
@cxx at_us(img, row, col, value);
@cxx ptr_val<unsigned short>(img, row, col, value);
elseif (cvtypeval(img) == CV_32FC1)
@cxx at_f(img, row, col, value);
@cxx ptr_val<float>(img, row, col, value);
elseif (cvtypeval(img) == CV_64FC1)
@cxx at_d(img, row, col, value);
# RGB images (value:: std::vector<double>)
@cxx ptr_val<double>(img, row, col, value);
# RGB images
elseif (cvtypeval(img) == CV_8SC3)
@cxx at_vc(img, row, col, value);
@cxx ptr_val3<char>(img, row, col, value);
elseif (cvtypeval(img) == CV_8UC3)
@cxx at_v3b(img, row, col, value);
@cxx ptr_val3<unsigned char>(img, row, col, value);
elseif (cvtypeval(img) == CV_16SC3)
@cxx at_v3s(img, row, col, value);
@cxx ptr_val3<short>(img, row, col, value);
elseif (cvtypeval(img) == CV_16UC3)
@cxx at_v3us(img, row, col, value);
@cxx ptr_val3<unsigned short>(img, row, col, value);
elseif (cvtypeval(img) == CV_32SC3)
@cxx at_v3i(img, row, col, value);
@cxx ptr_val3<int>(img, row, col, value);
elseif (cvtypeval(img) == CV_32FC3)
@cxx at_v3f(img, row, col, value);
@cxx ptr_val3<float>(img, row, col, value);
elseif (cvtypeval(img) == CV_64FC3)
@cxx at_v3d(img, row, col, value);
@cxx ptr_val3<double>(img, row, col, value);
else throw(ArgumentError("Image format not recognized!"))
end
end
Expand All @@ -216,10 +111,9 @@ cxx"""
// grayscale/binary image
void setgray(cv::Mat img, int val)
{
for(int row = 0; row < img.rows; ++row) {
for(int row=0; row < img.rows; ++row) {
uchar* p = img.ptr<uchar>(row);
for(int col = 0; col < img.cols; ++col) {
//points to each pixel value in turn assuming a CV_8UC1 greyscale image
for(int col=0; col < img.cols; ++col){
*p++ = val;
}
}
Expand All @@ -228,28 +122,26 @@ void setgray(cv::Mat img, int val)
// color image
void setcolor(cv::Mat img, std::vector<int> color)
{
int rows= img.rows;
int cols= img.cols;
int rows = img.rows;
int cols = img.cols;

for (int row=0; row<rows; row++)
{
for (int col=0; col<cols; col++)
{
cv::Point3_<uchar>* p = img.ptr<cv::Point3_<uchar>>(row,col);
p->x = color[0]; //B
p->y = color[1]; //G
p->z = color[2]; //R
}
}
for(int row=0; row < rows; ++row){
for(int col=0; col < cols; ++col){
cv::Point3_<uchar>* p = img.ptr<cv::Point3_<uchar>>(row, col);
p->x = color[0]; //B
p->y = color[1]; //G
p->z = color[2]; //R
}
}
}
"""

# for grayscale/binary
# for grayscale / binary
function setgray(img, val)
@cxx setgray(img, val)
end

# color/RGB
# color / RGB
function setcolor(img, color)
@cxx setcolor(img, color)
@cxx setcolor(img, color)
end
Loading