module interface export np2juliaImage, juliaImg2npImg, imgScalePadding, url_to_image using Images, Colors, FileIO, HTTP # using Luxor using CondaPkg; CondaPkg.add_pip("pybase64"); CondaPkg.add_pip("opencv-python"); CondaPkg.add_pip("scikit-image"); CondaPkg.add_pip("Pillow"); CondaPkg.add_pip("numpy"); using PythonCall # np = pyimport("numpy") # base64 = pyimport("pybase64") # cv = pyimport("cv2") # # equivalent to from urllib.request import urlopen in python # urlopen = pyimport("urllib.request" => "urlopen") const py_np = PythonCall.pynew() const py_cv2 = PythonCall.pynew() const py_io = PythonCall.pynew() function __init__() PythonCall.pycopy!(py_np, pyimport("numpy")) PythonCall.pycopy!(py_cv2, pyimport("cv2")) # equivalent to from urllib.request import urlopen in python PythonCall.pycopy!(py_io, pyimport("skimage" => "io")) end #------------------------------------------------------------------------------------------------100 """ get image from url, image in PythonCall python-obj numpy array """ function url_to_image(url) # read image directly from url julia_rgb_img = FileIO.load(HTTP.URI(url)) np_rgb_img, np_bgr_img = juliaImg2npImg(julia_rgb_img) cv2_bgr_img = np_bgr_img # opencv use BGR image return julia_rgb_img, np_rgb_img, cv2_bgr_img end # function url_to_image(url) # OLD version use python to read url # np_rgb_img = py_io.imread(url) # cv2_bgr_img = py_cv2.cvtColor(np_rgb_img, py_cv2.COLOR_RGB2BGR) # # convert cv2 img to julia img # julia_array_img = pyconvert(Array, cv2_bgr_img) # julia_rgb_img = np2juliaImage(julia_array_img) # # read image directly from url not converting from cv2 image # julia_native_rgb_img = FileIO.load(HTTP.URI(url)) # return julia_native_rgb_img, julia_rgb_img, cv2_bgr_img # end """ Convert "julia array FROM opencv numpy array image" into RGB image # Example julia> using CondaPkg; CondaPkg.add("opencv"); julia> using PythonCall julia> cv2 = pyimport("cv2") # import opencv julia> cv2_bgr_img = cv2.imread("20.jpg") # julia's PythonCall python-obj numpy array julia> julia_array_img = pyconvert(Array, cv2_bgr_img) # resulted in julia array but in cv2-numpy's row-major BGR format julia> julia_rgb_img = np2juliaImage(julia_array_img) # julia RGB image """ np2juliaImage(img::AbstractArray) = RGB.(reinterpretc(BGR{N0f8}, PermutedDimsArray(img, (3, 1, 2)))) """ Convert julia RGB image to numpy-ready-julia-array BGR image # Example julia> using Images julia> img = load("20.jpg") # julia RGB image julia> img_bgr = juliaImg2npImg(img) # ready to use with python numpy # After getting img_bgr, get python's numpy array in pycall obj julia> using CondaPkg; CondaPkg.add("numpy"); julia> using PythonCall julia> np = pyimport("numpy") julia> img_np = np.array(img_bgr) # julia's PythonCall python-obj numpy array can be passed to PythonCall's python function """ function juliaImg2npReadyImg(img_julia_RGB::Matrix{RGB{N0f8}}) #TODO convert img to numpy using PythonCall # julia image use 0-1 color range but python's opencv use 0-255 color range img_rgb2 = img_julia_RGB .* 255; imgch = channelview(img_rgb2); imgch = Int.(imgch) # opencv use Integer npReady_rgb_img = PermutedDimsArray(imgch, (2, 3, 1)); # build BGR image from RGB image because opencv use BGR format npReady_bgr_img = [ npReady_rgb_img[:,:,3];;; # blue npReady_rgb_img[:,:,2];;; # green npReady_rgb_img[:,:,1] # red ]; # return is Julia array, ready to be converted to numpy return npReady_rgb_img, npReady_bgr_img end function juliaImg2npImg(img_julia_RGB::Matrix{RGB{N0f8}}) npReady_rgb_Img, npReady_bgr_img = juliaImg2npReadyImg(img_julia_RGB) np_rgb_img = py_np.array(npReady_rgb_Img) np_bgr_img = py_np.array(npReady_bgr_img) return np_rgb_img, np_bgr_img # PythonCall wrapped numpy array end #------------------------------------------------------------------------------------------------100 """ Scale image to 1 specific dimension with padding. The longest side of an image will be used as primary dimension. """ function imgScalePadding(img::T, dimension::Integer, paddingType=nothing) where T <:DenseMatrix{RGB{N0f8}} w, h = size(img) # width = horizonal length, high = vertical length primaryDimension = w > h ? w : h dim = primaryDimension == w ? 1 : 2 percentage_scale = dimension / size(img)[dim]; new_size = trunc.(Int, size(img) .* percentage_scale); img_rescaled = imresize(img, new_size); return img_rescaled end end # interface