row / column major with PythonCall and numpy + OpenCV
I am trying to create an image processing program using PythonCall.jl and the Python version of OpenCV.
The specification I have in mind now is to create the pixel array as a 2-dimensional array img[y,x]
with row major so that the arrangement is natural on the OpenCV side. As a result, on the Julia side, I will treat it as a transposed image like img[x,y]
.
Python(OpenCV) → Julia
On the Julia side, I’m able to receive ndarray as I expected. However, when I call pyconvert()
to convert this to a Julia Array, “varies the fastest” axis is converted to y-axis by copying. I don’t care if it results in a
vertically long image, I want “varies the fastest” axis to remain the x-axis.
using BenchmarkTools
using PythonCall
using Images
np = pyimport("numpy")
cv2 = pyimport("cv2")
img_j = load("logo.png")
h, w = size(img_j)
(186, 288)
from_py = cv2.imread("logo.png", cv2.IMREAD_GRAYSCALE)
from_py.flags, from_py.shape, from_py.strides
(<py C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
>, <py (186, 288)>, <py (288, 1)>)
from_py_to_jl = @btime pyconvert(Array, from_py)
typeof(from_py_to_jl), size(from_py_to_jl), strides(from_py_to_jl)
172.619 μs (26 allocations: 53.47 KiB)
(Matrix{UInt8}, (186, 288), (1, 186))
Julia → Python(OpenCV)
It seems that I need to explicitly Py(x).to_numpy()
to pass the Julia array to the OpenCV function. This will create a ndarray that is F_CONTIGUOUS
without copying. This is a natural specification with no problem, but I want to create a ndarray that is C_CONTIGUOUS
without copying. This will be correctly recognized by OpenCV as a horizontal image.
from_jl = zeros(UInt8,w,h)
typeof(from_jl), size(from_jl), strides(from_jl)
(Matrix{UInt8}, (288, 186), (1, 288))
from_jl_to_py = @btime Py(from_jl).to_numpy()
from_jl_to_py.flags, from_jl_to_py.shape, from_jl_to_py.strides
7.276 μs (19 allocations: 544 bytes)
(<py C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
>, <py (288, 186)>, <py (1, 288)>)
To summarize my question.
-
How can I convert the ndarray received from the Python side into a Julia Array without copying and changing the “varies the fastest” axis?
-
How can I create a
C_CONTIGUOUS
ndarray withPy(x).to_numpy()
?
Please excuse my poor English.
The word “varies the fastest” is borrowed from Glossary — NumPy v1.13 Manual .