Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change julia array to C++ vector #27

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

kvmanohar22
Copy link
Contributor

@kvmanohar22 kvmanohar22 commented Mar 17, 2017

Encountered this bug while testing the test case 6.
With the earlier implementation of conversion of julia array to C++, I used to get the following error :

test 6: Conversion of images from Images.jl to OpenCV Mat
:1:1: error: no matching function for call to 'at_u'
^
__cxxjl_45.cpp:6:6: note: candidate function not viable: no known conversion from 'std::vector<double, std::allocator<double> >' to 'double' for 4th argument
void at_u(cv::Mat &img, int row, int col, double val)
     ^
__cxxjl_45.cpp:1:5: note: candidate function not viable: requires 3 arguments, but 4 were provided
int at_u(cv::Mat &img, int row, int col)
    ^
:1:1: error: no matching function for call to 'at_s'
^
__cxxjl_45.cpp:17:6: note: candidate function not viable: no known conversion from 'std::vector<double, std::allocator<double> >' to 'double' for 4th argument
void at_s(cv::Mat &img, int row, int col, double val)
     ^
__cxxjl_45.cpp:12:5: note: candidate function not viable: requires 3 arguments, but 4 were provided
int at_s(cv::Mat &img, int row, int col)
    ^
:1:1: error: no matching function for call to 'at_us'
^
__cxxjl_45.cpp:28:6: note: candidate function not viable: no known conversion from 'std::vector<double, std::allocator<double> >' to 'double' for 4th argument
void at_us(cv::Mat &img, int row, int col, double val)
     ^
__cxxjl_45.cpp:23:5: note: candidate function not viable: requires 3 arguments, but 4 were provided
int at_us(cv::Mat &img, int row, int col)
    ^
:1:1: error: no matching function for call to 'at_f'
^
__cxxjl_45.cpp:39:6: note: candidate function not viable: no known conversion from 'std::vector<double, std::allocator<double> >' to 'double' for 4th argument
void at_f(cv::Mat &img, int row, int col, double val)
     ^
__cxxjl_45.cpp:34:7: note: candidate function not viable: requires 3 arguments, but 4 were provided
float at_f(cv::Mat &img, int row, int col)
      ^
:1:1: error: no matching function for call to 'at_d'
^
__cxxjl_45.cpp:50:6: note: candidate function not viable: no known conversion from 'std::vector<double, std::allocator<double> >' to 'double' for 4th argument
void at_d(cv::Mat &img, int row, int col, double val)
     ^
__cxxjl_45.cpp:45:8: note: candidate function not viable: requires 3 arguments, but 4 were provided
double at_d(cv::Mat &img, int row, int col)
       ^

The present implementation solves the problem.

@@ -194,18 +194,25 @@ function pixset(img, row::Int, col::Int, value)
@cxx at_d(img, row, col, value);
# RGB images (value:: std::vector<double>)
elseif (cvtypeval(img) == CV_8SC3)
cppvec = tostdvec(value)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is cppvec passed next? I see that you pass colorvec to pixset and then convert the julia array to an std::vectorwith tostdvec. It seems then you should be passing it further e.g, @cxx at_vc(img, row, col, cppvec); as so on to the other cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh no! I forgot to replace value with cppvec.

@@ -195,25 +195,25 @@ function pixset(img, row::Int, col::Int, value)
# RGB images (value:: std::vector<double>)
elseif (cvtypeval(img) == CV_8SC3)
cppvec = tostdvec(value)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure still whether the conversion to std::vec should be done in this function.
In any case, there is no need to repeat cppvec = tostdvec(value) in every elseif statement.
Just state it once as shown below.

function pixset(img, row::Int, col::Int, value)
  (row < 0 || col < 0 || row > rows(img) || col > cols(img)) ? throw(BoundsError()) : nothing
  cppvec = tostdvec(value)

. . . code not shown . . .

  elseif (cvtypeval(img) == CV_8SC3)
    @cxx at_vc(img, row, col, cppvec);
  elseif (cvtypeval(img) == CV_8UC3)
    @cxx at_v3b(img, row, col, cppvec);
  elseif (cvtypeval(img) == CV_16SC3)
    @cxx at_v3s(img, row, col, cppvec);
  elseif (cvtypeval(img) == CV_16UC3)
    @cxx at_v3us(img, row, col, cppvec);
  elseif (cvtypeval(img) == CV_32SC3)
    @cxx at_v3i(img, row, col, cppvec);
  elseif (cvtypeval(img) == CV_32FC3)
    @cxx at_v3f(img, row, col, cppvec);
  elseif (cvtypeval(img) == CV_64FC3)
    @cxx at_v3d(img, row, col, cppvec);
  else throw(ArgumentError("Image format not recognized!"))
  end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure still whether the conversion to std::vec should be done in this function

Yes, I think whether the conversion is made later on or before shouldn't make difference. But unexpectedly I found that the previous implementation led to the errors as mentioned above. Shall I add the details to reproduce the error ?

Copy link
Owner

@maxruby maxruby Mar 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please share the details which led to this error so we have it on record.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To reproduce the error :
In test/runtests.jl, import the following

using OpenCV
using Images
using Base.Test
using FileIO

In test/jl/tests.jl, add the following test function

function test6()
   println("test 6: Conversion of images from Images.jl to OpenCV Mat")
   filename = joinpath(Pkg.dir("OpenCV"), "./test/images/mandrill.jpg")
   image = FileIO.load(filename)
   dst = convertToMat(image)
   println("Image converted to Mat successfully")
end

test6()

src/OpenCV_Mat.jl as in master branch.
In src/OpenCV_ImageSupport.jl, the following function definition :

function convertToMat(image)
    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(512, 512, CV_8UC1); end
       if (cd == 3); mat = Mat(512, 512, CV_8UC3); end
    elseif (typeof(img[1,1,1].i) == Float32)
       if (cd < 3); mat = Mat(512, 512, CV_32FC1); end
       if (cd == 3); mat = Mat(512, 512, CV_32FC3); end
    elseif (typeof(img[1,1,1].i) == Float64)
       if (cd < 3); mat = Mat(512, 512, CV_64FC1); end
       if (cd == 3); mat = Mat(512, 512, CV_64FC3); end
    else
       throw(ArgumentError("Pixel format not supported!"))
    end

    if (cd < 3)   # grayscale or binary
        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:512     # index row first (Mat is row-major order)
            for k =1:512  # 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
        end
    end

    return(mat)
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants