Skip to content

[GSoC] Julia - phase 2 #3009

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

Merged
merged 4 commits into from
Sep 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion modules/julia/gen/cpp_files/jlcv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ typedef flann::SearchParams flann_SearchParams;
#include <opencv2/dnn.hpp>
typedef cv::dnn::DictValue LayerId;
typedef cv::dnn::Backend dnn_Backend;
typedef cv::dnn::Target dnn_Target;
#endif

#ifdef HAVE_OPENCV_CALIB3D
Expand Down Expand Up @@ -104,7 +105,7 @@ struct force_enum<T, false>{
};
template<typename T>
struct force_enum<T, true>{
using Type = int;
using Type = int64_t;
};

template<typename T>
Expand Down
101 changes: 51 additions & 50 deletions modules/julia/gen/defval.txt
Original file line number Diff line number Diff line change
@@ -1,102 +1,103 @@
Float64|0.1|0.1
Float64|1.0|1.0
Float64|0|0
Int32|NORM_L2|cv_NORM_L2
Int64|NORM_L2|cv_NORM_L2
Float64|0.04|0.04
Bool|true|true
Float32|0.0f|0
Float64|0.0f|0
Float64|DBL_MAX|typemax(Float64)
Ptr{Float32}|Ptr<float>()|cpp_to_julia(PtrifloatkOP())
Int32|CV_32F|CV_32F
Int32|20|20
Int64|CV_32F|CV_32F
Int64|20|20
Array{String, 1}|std::vector<String>()|cpp_to_julia(stdggvectoriStringkOP())
Float32|1|1
Float64|1|1
TermCriteria|TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1)|cpp_to_julia(TermCriteriaOTermCriteriaggMAXRITERRTermCriteriaggEPSSbSXP())
Int32|4|4
Int32|LINE_8|cv_LINE_8
Float32|0.5|0.5
Float32|0.5f|0.5
Int32|MARKER_CROSS|cv_MARKER_CROSS
Int64|4|4
Int64|LINE_8|cv_LINE_8
Float64|0.5|0.5
Float64|0.5f|0.5
Int64|MARKER_CROSS|cv_MARKER_CROSS
Float64|1|1
Point{Int32}|Point(-1,-1)|cpp_to_julia(PointOTXSTXP())
Float64|CV_PI*0.5|pi*0.5
Int32|QT_FONT_NORMAL|cv_QT_FONT_NORMAL
Int64|QT_FONT_NORMAL|cv_QT_FONT_NORMAL
Point{Int32}|Point()|cpp_to_julia(PointOP())
Float64|CV_PI|pi
Float32|-1|-1
Int32|300|300
Int32|3|3
Float64|-1|-1
Int64|300|300
Int64|3|3
String|""|""
Scalar|Scalar()|cpp_to_julia(ScalarOP())
Float32|1.f|1
Float64|1.f|1
Array{Int32, 1}|std::vector<int>()|cpp_to_julia(stdggvectoriintkOP())
InputArray|Mat()|CxxMat()
Int32|BORDER_DEFAULT|cv_BORDER_DEFAULT
Int32|CV_32S|CV_32S
Int32|IMREAD_COLOR|cv_IMREAD_COLOR
Int64|BORDER_DEFAULT|cv_BORDER_DEFAULT
Int64|CV_32S|CV_32S
Int64|IMREAD_COLOR|cv_IMREAD_COLOR
Float64|100|100
Size{Int32}|Size(8, 8)|cpp_to_julia(SizeOeSGeP())
Array{InputArray, 1}||Array{InputArray, 1}()
Int32|GC_EVAL|cv_GC_EVAL
Int32|8|8
Int32|DIST_LABEL_CCOMP|cv_DIST_LABEL_CCOMP
Int32|CAP_ANY|cv_CAP_ANY
Float32|0|0
Int32|-1|-1
Int64|GC_EVAL|cv_GC_EVAL
Int64|8|8
Int64|DIST_LABEL_CCOMP|cv_DIST_LABEL_CCOMP
Int64|CAP_ANY|cv_CAP_ANY
Float64|0|0
Int64|-1|-1
Float64|-DBL_MAX|-typemax(Float64)
Scalar|Scalar::all(0)|cpp_to_julia(ScalarggallOWP())
InputArray||CxxMat()
Int32|QT_STYLE_NORMAL|cv_QT_STYLE_NORMAL
Int32|INTER_LINEAR|cv_INTER_LINEAR
Int64|QT_STYLE_NORMAL|cv_QT_STYLE_NORMAL
Int64|INTER_LINEAR|cv_INTER_LINEAR
Bool|false|false
Int32|CV_64F|CV_64F
Int64|CV_64F|CV_64F
Point{Int32}|Point(-1, -1)|cpp_to_julia(PointOTXSGTXP())
Scalar|morphologyDefaultBorderValue()|cpp_to_julia(morphologyDefaultBorderValueOP())
Int32|IMREAD_ANYCOLOR|cv_IMREAD_ANYCOLOR
Int32|INT_MAX|typemax(Int32)
Int64|IMREAD_ANYCOLOR|cv_IMREAD_ANYCOLOR
Int64|INT_MAX|typemax(Int32)
String|String()|""
Float64|1.|1
Int32|WINDOW_AUTOSIZE|cv_WINDOW_AUTOSIZE
Int32|DECOMP_LU|cv_DECOMP_LU
Int64|WINDOW_AUTOSIZE|cv_WINDOW_AUTOSIZE
Int64|DECOMP_LU|cv_DECOMP_LU
Float64|40.0|40.0
Int32|BORDER_CONSTANT|cv_BORDER_CONSTANT
Int64|BORDER_CONSTANT|cv_BORDER_CONSTANT
Array{UInt8, 1}|std::vector<uchar>()|cpp_to_julia(stdggvectoriucharkOP())
Int32|0|0
Int64|0|0
Float64|255.|255
Scalar|Scalar(1)|cpp_to_julia(ScalarOXP())
Int32|1|1
Int64|1|1
Size{Int32}|Size()|cpp_to_julia(SizeOP())
TermCriteria|TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 20, FLT_EPSILON)|cpp_to_julia(TermCriteriaOTermCriteriaggEPSGRGTermCriteriaggCOUNTSGYWSGFLTREPSILONP())
Int32|RANSAC|cv_RANSAC
Float32|8.0|8.0
Int64|RANSAC|cv_RANSAC
Float64|8.0|8.0
Float64|-1|-1
Int32|21|21
Int64|21|21
TermCriteria|TermCriteria( TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON)|TermCriteriaOGTermCriteriaggCOUNTGRGTermCriteriaggEPSSGZWSGDBLREPSILONP
TermCriteria|TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6)|TermCriteriaOTermCriteriaggCOUNTRTermCriteriaggEPSSGZWSGXeTcP
Int32|CALIB_CB_SYMMETRIC_GRID|cv_CALIB_CB_SYMMETRIC_GRID
Int64|CALIB_CB_SYMMETRIC_GRID|cv_CALIB_CB_SYMMETRIC_GRID
InputArray|cv::Mat()|CxxMat()
Int32|SOLVEPNP_ITERATIVE|cv_SOLVEPNP_ITERATIVE
Int64|SOLVEPNP_ITERATIVE|cv_SOLVEPNP_ITERATIVE
Float64|3|3
Int32|CALIB_FIX_INTRINSIC|cv_CALIB_FIX_INTRINSIC
Int64|CALIB_FIX_INTRINSIC|cv_CALIB_FIX_INTRINSIC
Float64|5|5
Float64|0.99|0.99
Int32|CALIB_ZERO_DISPARITY|cv_CALIB_ZERO_DISPARITY
Int64|CALIB_ZERO_DISPARITY|cv_CALIB_ZERO_DISPARITY
size_t|2000|2000
SolvePnPMethod|SOLVEPNP_ITERATIVE|cv_SOLVEPNP_ITERATIVE
Float64|0.0|0.0
Ptr{Feature2D}|SimpleBlobDetector::create()|SimpleBlobDetectorggcreateOP
Int32|StereoSGBM::MODE_SGBM|StereoSGBMggMODERSGBM
Int32|CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE|cv_CALIB_CB_ADAPTIVE_THRESH + cv_CALIB_CB_NORMALIZE_IMAGE
Int64|StereoSGBM::MODE_SGBM|StereoSGBMggMODERSGBM
Int64|CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE|cv_CALIB_CB_ADAPTIVE_THRESH + cv_CALIB_CB_NORMALIZE_IMAGE
Float64|3.|3
size_t|10|10
Int32|16|16
Int64|16|16
Point{Float64}|Point2d(0, 0)|PointYdOWSGWP
Int32|2000|2000
Int32|FM_RANSAC|cv_FM_RANSAC
Int32|100|100
Int64|2000|2000
Int64|FM_RANSAC|cv_FM_RANSAC
Int64|100|100
TermCriteria|TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON)|TermCriteriaOTermCriteriaggCOUNTGRGTermCriteriaggEPSSGXWWSGDBLREPSILONP
HandEyeCalibrationMethod|CALIB_HAND_EYE_TSAI|cv_CALIB_HAND_EYE_TSAI
Float32|0.8F|0.8
Int32|fisheye::CALIB_FIX_INTRINSIC|cv_fisheye_CALIB_FIX_INTRINSIC
Float64|0.8F|0.8
Int64|fisheye::CALIB_FIX_INTRINSIC|cv_fisheye_CALIB_FIX_INTRINSIC
Float64|0.999|0.999
Float64|0.995|0.995
Float64|0.995|0.995
Int64|1000|1000
1 change: 1 addition & 0 deletions modules/julia/gen/funclist.csv
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ cv.dnn.Model.setInputScale
cv.dnn.Model.setInputCrop
cv.dnn.Model.setInputSwapRB
cv.dnn.Model.setInputParams
cv.dnn.Model.setPreferableTarget
Copy link
Member

Choose a reason for hiding this comment

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

Could you please add setPreferableBackend too?

cv.dnn.Model.predict
cv.dnn.ClassificationModel.ClassificationModel
cv.dnn.ClassificationModel.classify
Expand Down
47 changes: 37 additions & 10 deletions modules/julia/gen/gen3_cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,23 @@ def get_setters(self):
class FuncVariant(FuncVariant):

def get_return(self):
outstr = ""
for arg in self.inlist+self.optlist:
if arg.tp not in pass_by_val_types and arg.tp not in enums and self.promote_type(arg.tp)!=arg.tp:
outstr = outstr + "%s=%s_down;\n"%(arg.name, arg.name)

if len(self.outlist)==0:
return ";"
return outstr+";"
elif len(self.outlist)==1:
return "return %s;" % ( ('(int)' if self.outlist[0].tp in enums else '') + self.outlist[0].name)
return "return make_tuple(%s);" % ",".join(["move(%s)" % (('(int)' if x.tp in enums else '') +x.name) for x in self.outlist])
return outstr+"return %s;" % ( ('(int64_t)' if self.outlist[0].tp in enums else ('' if self.promote_type(self.outlist[0].tp)==self.outlist[0].tp else '(%s)'%self.promote_type(self.outlist[0].tp))) + self.outlist[0].name)
return outstr+"return make_tuple(%s);" % ",".join(["move(%s)" % (('(int64_t)' if x.tp in enums else ('' if self.promote_type(x.tp)==x.tp else '(%s)'%self.promote_type(x.tp))) +x.name) for x in self.outlist])

def promote_type(self, tp):
if tp=='int':
return 'long long'
elif tp =='float':
return 'double'
return tp

def get_argument(self, isalgo):
args = self.inlist + self.optlist
Expand All @@ -142,13 +154,13 @@ def get_argument(self, isalgo):
print("PATHWAY NOT TESTED")
argnamelist.append(arg.tp[:-1] +"& "+arg.name)
elif arg.tp in enums:
argnamelist.append("int& " + arg.name)
argnamelist.append("int64_t& " + arg.name)
else:
if arg.tp=='bool':
# Bool pass-by-reference is broken
argnamelist.append(arg.tp+" " +arg.name)
else:
argnamelist.append(arg.tp + "& "+arg.name)
argnamelist.append(self.promote_type(arg.tp) + "& "+arg.name)
# argnamelist = [(arg.tp if arg.tp not in pass_by_val_types else arg.tp[:-1]) +"& "+arg.name for arg in args]
argstr = ", ".join(argnamelist)
return argstr
Expand All @@ -157,6 +169,10 @@ def get_def_outtypes(self):
outstr = ""
for arg in self.deflist:
outstr = outstr + "%s %s;"%(arg.tp if arg.tp not in pass_by_val_types else arg.tp[:-1], arg.name)
for arg in self.inlist+self.optlist:
if arg.tp not in pass_by_val_types and arg.tp not in enums and self.promote_type(arg.tp)!=arg.tp:
outstr = outstr + "%s %s_down=(%s)%s;"%(arg.tp if arg.tp not in pass_by_val_types else arg.tp[:-1], arg.name, arg.tp, arg.name)

return outstr

def get_retval(self, isalgo):
Expand All @@ -171,7 +187,15 @@ def get_retval(self, isalgo):
elif x.tp in enums:
arlist.append("(%s)%s" %(x.tp, x.name))
else:
arlist.append(x.name)
if self.promote_type(x.tp) == x.tp:
arlist.append(x.name)
else:
if len([y for y in self.inlist+self.optlist if y.name==x.name])>0:
# print("ss")
arlist.append("%s_down" %(x.name))
else:
arlist.append(x.name)

argstr = ", ".join(arlist)
if self.classname and not self.isstatic:
stra = stra + "cobj%s%s(%s); " %("->" if isalgo else ".",self.name.split('::')[-1], argstr)
Expand All @@ -189,8 +213,11 @@ def get_cons_code(self, name, mapped_name):
elif x.tp in enums:
arglist.append("(%s)%s" %(x.tp, x.name))
else:
arglist.append(x.name)

if self.promote_type(x.tp) == x.tp:
arglist.append(x.name)
else:
# print("ss")
arglist.append("%s_down" %(x.name))
return 'mod.method("%s", [](%s) { %s return jlcxx::create<%s>(%s);});' % (self.get_wrapper_name(), self.get_argument(False), self.get_def_outtypes(), name, " ,".join(arglist))

def get_complete_code(self, classname, isalgo=False):
Expand Down Expand Up @@ -255,13 +282,13 @@ def sort_classes(classes):
# cpp_code.write('\n mod.add_bits<{0}>("{1}", jlcxx::julia_type("CppEnum"));'.format(e2[0], e2[1]))
enums.append(e2[0])
enums.append(e2[1])
enums.append(e2[0].replace("cv::", ""))
enums.append(e2[0].replace("cv::", "").replace("::", '_'))


for tp in ns.register_types:
cpp_code.write(' mod.add_type<%s>("%s");\n' %(tp, normalize_class_name(tp)))


# print(enums)
for name, ns in namespaces.items():

nsname = name.replace("::", "_")
Expand Down
15 changes: 11 additions & 4 deletions modules/julia/gen/gen3_julia_cxx.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,25 +104,32 @@ def overload_set(self):

class FuncVariant(FuncVariant):

def promote_type(self, tp):
if tp=='int':
return 'long long'
elif tp =='float':
return 'double'
return tp


def get_argument_full(self, classname='', isalgo = False):
arglist = self.inlist + self.optlist

argnamelist = [arg.name+"::"+(handle_jl_arg(arg.tp) if handle_jl_arg(arg.tp) not in pass_by_val_types else handle_jl_arg(arg.tp)[:-1]) for arg in arglist]
argnamelist = [arg.name+"::"+(handle_jl_arg(self.promote_type(arg.tp)) if handle_jl_arg(arg.tp) not in pass_by_val_types else handle_jl_arg(self.promote_type(arg.tp[:-1]))) for arg in arglist]
argstr = ", ".join(argnamelist)
return argstr

def get_argument_opt(self, ns=''):
# [print(arg.default_value,":",handle_def_arg(arg.default_value, handle_jl_arg(arg.tp))) for arg in self.optlist]
try:
str2 = ", ".join(["%s::%s = %s(%s)" % (arg.name, handle_jl_arg(arg.tp), handle_jl_arg(arg.tp) if (arg.tp == 'int' or arg.tp=='float' or arg.tp=='double') else '', handle_def_arg(arg.default_value, handle_jl_arg(arg.tp), ns)) for arg in self.optlist])
str2 = ", ".join(["%s::%s = %s(%s)" % (arg.name, handle_jl_arg(self.promote_type(arg.tp)), handle_jl_arg(self.promote_type(arg.tp)) if (arg.tp == 'int' or arg.tp=='float' or arg.tp=='double') else '', handle_def_arg(arg.default_value, handle_jl_arg(self.promote_type(arg.tp)), ns)) for arg in self.optlist])
return str2
except KeyError:
return ''

def get_argument_def(self, classname, isalgo):
arglist = self.inlist
argnamelist = [arg.name+"::"+(handle_jl_arg(arg.tp) if handle_jl_arg(arg.tp) not in pass_by_val_types else handle_jl_arg(arg.tp)[:-1]) for arg in arglist]
argnamelist = [arg.name+"::"+(handle_jl_arg(self.promote_type(arg.tp)) if handle_jl_arg(self.promote_type(arg.tp)) not in pass_by_val_types else handle_jl_arg(self.promote_type(arg.tp[:-1]))) for arg in arglist]
argstr = ", ".join(argnamelist)
return argstr

Expand Down Expand Up @@ -170,7 +177,7 @@ def gen(srcfiles):
nsname = name
for e1,e2 in ns.enums.items():
# jl_code.write('\n const {0} = Int32'.format(e2[0]))
jl_code.write('\n const {0} = Int32 \n'.format(e2[1]))
jl_code.write('\n const {0} = Int64 \n'.format(e2[0].replace("cv::", "").replace("::", "_")))

# Do not duplicate functions. This should prevent overwriting of Mat function by UMat functions
function_signatures = []
Expand Down
4 changes: 2 additions & 2 deletions modules/julia/gen/jl_cxx_files/types_conversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function julia_to_cpp(var::Array{Vec{T, N}, 1}) where {T, N}
return ret
end

function julia_to_cpp(var::Array{T}) where {T}
function julia_to_cpp(var::Array{T, 1}) where {T}
if size(var, 1) == 0
return CxxWrap.StdVector{T}()
end
Expand Down Expand Up @@ -69,7 +69,7 @@ end

function cpp_to_julia(var::CxxWrap.StdVector{T}) where {T}
if size(var, 1) == 0
return Array{T}()
return Array{T, 1}()
end
ret = Array{typeof(cpp_to_julia(var[1])), 1}()
for x in var
Expand Down
5 changes: 3 additions & 2 deletions modules/julia/gen/typemap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Mat:InputArray
KeyPoint:KeyPoint
Moments:Moments
RNG*:NONCONVERT4
int:Int32
int:Int64
vector<float>:Array{Float32, 1}
vector<Rect>:Array{Rect{Int32}, 1}
Scalar:Scalar
Expand All @@ -42,11 +42,12 @@ vector<string>:Array{String, 1}
vector<Point2f>:Array{Point{Float32}, 1}
Size:Size{Int32}
vector<MatShape>:Array{Array{Int32, 1}, 1}
float:Float32
float:Float64
Ptr<float>:Ptr{Float32}
vector<Vec6f>:Array{Vec{Float32, 6}, 1}
Ptr<FeatureDetector>:Ptr{Feature2D}
Point2d:Point{Float64}
SolvePnPMethod:SolvePnPMethod
CirclesGridFinderParameters:CirclesGridFinderParameters
HandEyeCalibrationMethod:HandEyeCalibrationMethod
long long:Int64
4 changes: 2 additions & 2 deletions modules/julia/test/test_dnn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ end

const cv = OpenCV
net = cv.dnn.DetectionModel(joinpath(ENV["OPENCV_TEST_DATA_PATH"], "dnn", "opencv_face_detector.pbtxt"),joinpath(ENV["OPENCV_TEST_DATA_PATH"], "dnn", "opencv_face_detector_uint8.pb"))
size0 = Int32(300)
size0 = 300

cv.dnn.setPreferableTarget(net, cv.dnn.DNN_TARGET_CPU)
cv.dnn.setInputMean(net, (104, 177, 123))
Expand All @@ -22,7 +22,7 @@ cv.dnn.setInputSize(net, size0, size0)

img = OpenCV.imread(joinpath(test_dir, "cascadeandhog", "images", "mona-lisa.png"))

classIds, confidences, boxes = cv.dnn.detect(net, img, confThreshold=Float32(0.5))
classIds, confidences, boxes = cv.dnn.detect(net, img, confThreshold=0.5)

box = (boxes[1].x, boxes[1].y, boxes[1].x+boxes[1].width, boxes[1].y+boxes[1].height)
expected_rect = (185,101,129+185,169+101)
Expand Down