/ext/opencv/cvmat.cpp

http://github.com/ryanfb/ruby-opencv · C++ · 5218 lines · 2671 code · 293 blank · 2254 comment · 255 complexity · ded9e7fe3ff7bdf9aa6be0064b9aa05c MD5 · raw file

Large files are truncated click here to view the full file

  1. /************************************************************
  2. cvmat.cpp -
  3. $Author: lsxi $
  4. Copyright (C) 2005-2008 Masakazu Yonekura
  5. ************************************************************/
  6. #include "cvmat.h"
  7. /*
  8. * Document-class: OpenCV::CvMat
  9. *
  10. * CvMat is basic 2D matrix class in OpenCV.
  11. *
  12. * C structure is here.
  13. * typedef struct CvMat{
  14. * int type;
  15. * int step;
  16. * int *refcount;
  17. * union
  18. * {
  19. * uchar *ptr;
  20. * short *s;
  21. * int *i;
  22. * float *fl;
  23. * double *db;
  24. * } data;
  25. * #ifdef __cplusplus
  26. * union
  27. * {
  28. * int rows;
  29. * int height;
  30. * };
  31. * union
  32. * {
  33. * int cols;
  34. * int width;
  35. * };
  36. * #else
  37. * int rows; // number of row
  38. * int cols; // number of columns
  39. * }CvMat;
  40. */
  41. __NAMESPACE_BEGIN_OPENCV
  42. __NAMESPACE_BEGIN_CVMAT
  43. #define SUPPORT_8UC1_ONLY(value) if (cvGetElemType(CVARR(value)) != CV_8UC1) {rb_raise(rb_eNotImpError, "support single-channel 8bit unsigned image only.");}
  44. #define SUPPORT_8U_ONLY(value) if (CV_MAT_DEPTH(cvGetElemType(CVARR(value))) != CV_8U) {rb_raise(rb_eNotImpError, "support 8bit unsigned image only.");}
  45. #define SUPPORT_C1_ONLY(value) if (CV_MAT_CN(cvGetElemType(CVARR(value))) != 1) {rb_raise(rb_eNotImpError, "support single-channel image only.");}
  46. #define SUPPORT_C1C3_ONLY(value) if (CV_MAT_CN(cvGetElemType(CVARR(value))) != 1 && CV_MAT_CN(cvGetElemType(CVARR(value))) != 3) {rb_raise(rb_eNotImpError, "support single-channel or 3-channnel image only.");}
  47. #define DRAWING_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("DRAWING_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("DRAWING_OPTION")), rb_intern("merge"), 1, op)
  48. #define DO_COLOR(op) VALUE_TO_CVSCALAR(rb_hash_aref(op, ID2SYM(rb_intern("color"))))
  49. #define DO_THICKNESS(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("thickness"))))
  50. #define DO_LINE_TYPE(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("line_type"))))
  51. #define DO_SHIFT(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("shift"))))
  52. #define DO_IS_CLOSED(op) ({VALUE _is_closed = rb_hash_aref(op, ID2SYM(rb_intern("is_closed"))); NIL_P(_is_closed) ? 0 : _is_closed == Qfalse ? 0 : 1;})
  53. #define GOOD_FEATURES_TO_TRACK_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("GOOD_FEATURES_TO_TRACK_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("GOOD_FEATURES_TO_TRACK_OPTION")), rb_intern("merge"), 1, op)
  54. #define GF_MAX(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("max"))))
  55. #define GF_MASK(op) MASK(rb_hash_aref(op, ID2SYM(rb_intern("mask"))))
  56. #define GF_BLOCK_SIZE(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("block_size"))))
  57. #define GF_USE_HARRIS(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("use_harris"))), 0)
  58. #define GF_K(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("k"))))
  59. #define FLOOD_FILL_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("FLOOD_FILL_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("FLOOD_FILL_OPTION")), rb_intern("merge"), 1, op)
  60. #define FF_CONNECTIVITY(op) NUM2INT(rb_hash_aref(op, ID2SYM(rb_intern("connectivity"))))
  61. #define FF_FIXED_RANGE(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("fixed_range"))), 0)
  62. #define FF_MASK_ONLY(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("mask_only"))), 0)
  63. #define FIND_CONTOURS_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("FIND_CONTOURS_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("FIND_CONTOURS_OPTION")), rb_intern("merge"), 1, op)
  64. #define FC_MODE(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("mode"))))
  65. #define FC_METHOD(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("method"))))
  66. #define FC_OFFSET(op)VALUE_TO_CVPOINT(rb_hash_aref(op, ID2SYM(rb_intern("offset"))))
  67. #define OPTICAL_FLOW_HS_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_HS_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_HS_OPTION")), rb_intern("merge"), 1, op)
  68. #define HS_LAMBDA(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("lambda"))))
  69. #define HS_CRITERIA(op) VALUE_TO_CVTERMCRITERIA(rb_hash_aref(op, ID2SYM(rb_intern("criteria"))))
  70. #define OPTICAL_FLOW_BM_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_BM_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_BM_OPTION")), rb_intern("merge"), 1, op)
  71. #define BM_BLOCK_SIZE(op) VALUE_TO_CVSIZE(rb_hash_aref(op, ID2SYM(rb_intern("block_size"))))
  72. #define BM_SHIFT_SIZE(op) VALUE_TO_CVSIZE(rb_hash_aref(op, ID2SYM(rb_intern("shift_size"))))
  73. #define BM_MAX_RANGE(op) VALUE_TO_CVSIZE(rb_hash_aref(op, ID2SYM(rb_intern("max_range"))))
  74. #define FIND_FUNDAMENTAL_MAT_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("FIND_FUNDAMENTAL_MAT_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("FIND_FUNDAMENTAL_MAT_OPTION")), rb_intern("merge"), 1, op)
  75. #define FFM_WITH_STATUS(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("with_status"))), 0)
  76. #define FFM_MAXIMUM_DISTANCE(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("maximum_distance"))))
  77. #define FFM_DESIRABLE_LEVEL(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("desirable_level"))))
  78. VALUE rb_klass;
  79. VALUE
  80. rb_class()
  81. {
  82. return rb_klass;
  83. }
  84. void define_ruby_class()
  85. {
  86. if (rb_klass)
  87. return;
  88. /*
  89. * opencv = rb_define_module("OpenCV");
  90. *
  91. * note: this comment is used by rdoc.
  92. */
  93. VALUE opencv = rb_module_opencv();
  94. rb_klass = rb_define_class_under(opencv, "CvMat", rb_cObject);
  95. rb_define_alloc_func(rb_klass, rb_allocate);
  96. VALUE drawing_option = rb_hash_new();
  97. rb_define_const(rb_klass, "DRAWING_OPTION", drawing_option);
  98. rb_hash_aset(drawing_option, ID2SYM(rb_intern("color")), cCvScalar::new_object(cvScalarAll(0)));
  99. rb_hash_aset(drawing_option, ID2SYM(rb_intern("thickness")), INT2FIX(1));
  100. rb_hash_aset(drawing_option, ID2SYM(rb_intern("line_type")), INT2FIX(8));
  101. rb_hash_aset(drawing_option, ID2SYM(rb_intern("shift")), INT2FIX(0));
  102. VALUE good_features_to_track_option = rb_hash_new();
  103. rb_define_const(rb_klass, "GOOD_FEATURES_TO_TRACK_OPTION", good_features_to_track_option);
  104. rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("max")), INT2FIX(0xFF));
  105. rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("mask")), Qnil);
  106. rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("block_size")), INT2FIX(3));
  107. rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("use_harris")), Qfalse);
  108. rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("k")), rb_float_new(0.04));
  109. VALUE flood_fill_option = rb_hash_new();
  110. rb_define_const(rb_klass, "FLOOD_FILL_OPTION", flood_fill_option);
  111. rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("connectivity")), INT2FIX(4));
  112. rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("fixed_range")), Qfalse);
  113. rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("mask_only")), Qfalse);
  114. VALUE find_contours_option = rb_hash_new();
  115. rb_define_const(rb_klass, "FIND_CONTOURS_OPTION", find_contours_option);
  116. rb_hash_aset(find_contours_option, ID2SYM(rb_intern("mode")), INT2FIX(CV_RETR_LIST));
  117. rb_hash_aset(find_contours_option, ID2SYM(rb_intern("method")), INT2FIX(CV_CHAIN_APPROX_SIMPLE));
  118. rb_hash_aset(find_contours_option, ID2SYM(rb_intern("offset")), cCvPoint::new_object(cvPoint(0,0)));
  119. VALUE optical_flow_hs_option = rb_hash_new();
  120. rb_define_const(rb_klass, "OPTICAL_FLOW_HS_OPTION", optical_flow_hs_option);
  121. rb_hash_aset(optical_flow_hs_option, ID2SYM(rb_intern("lambda")), rb_float_new(0.0005));
  122. rb_hash_aset(optical_flow_hs_option, ID2SYM(rb_intern("criteria")), cCvTermCriteria::new_object(cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1, 0.001)));
  123. VALUE optical_flow_bm_option = rb_hash_new();
  124. rb_define_const(rb_klass, "OPTICAL_FLOW_BM_OPTION", optical_flow_bm_option);
  125. rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("block_size")), cCvSize::new_object(cvSize(4, 4)));
  126. rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("shift_size")), cCvSize::new_object(cvSize(1, 1)));
  127. rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("max_range")), cCvSize::new_object(cvSize(4, 4)));
  128. VALUE find_fundamental_matrix_option = rb_hash_new();
  129. rb_define_const(rb_klass, "FIND_FUNDAMENTAL_MAT_OPTION", find_fundamental_matrix_option);
  130. rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("with_status")), Qfalse);
  131. rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("maximum_distance")), rb_float_new(1.0));
  132. rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("desirable_level")), rb_float_new(0.99));
  133. rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
  134. rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load_imageM), -1);
  135. // Ruby/OpenCV original functions
  136. rb_define_method(rb_klass, "method_missing", RUBY_METHOD_FUNC(rb_method_missing), -1);
  137. rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0);
  138. rb_define_method(rb_klass, "has_parent?", RUBY_METHOD_FUNC(rb_has_parent_q), 0);
  139. rb_define_method(rb_klass, "parent", RUBY_METHOD_FUNC(rb_parent), 0);
  140. rb_define_method(rb_klass, "inside?", RUBY_METHOD_FUNC(rb_inside_q), 1);
  141. rb_define_method(rb_klass, "to_IplConvKernel", RUBY_METHOD_FUNC(rb_to_IplConvKernel), 1);
  142. rb_define_method(rb_klass, "create_mask", RUBY_METHOD_FUNC(rb_create_mask), 0);
  143. rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0);
  144. rb_define_alias(rb_klass, "columns", "width");
  145. rb_define_alias(rb_klass, "cols", "width");
  146. rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0);
  147. rb_define_alias(rb_klass, "rows", "height");
  148. rb_define_method(rb_klass, "depth", RUBY_METHOD_FUNC(rb_depth), 0);
  149. rb_define_method(rb_klass, "channel", RUBY_METHOD_FUNC(rb_channel), 0);
  150. rb_define_method(rb_klass, "data", RUBY_METHOD_FUNC(rb_data), 0);
  151. rb_define_method(rb_klass, "clone", RUBY_METHOD_FUNC(rb_clone), 0);
  152. rb_define_method(rb_klass, "copy", RUBY_METHOD_FUNC(rb_copy), -1);
  153. rb_define_method(rb_klass, "to_8u", RUBY_METHOD_FUNC(rb_to_8u), 0);
  154. rb_define_method(rb_klass, "to_8s", RUBY_METHOD_FUNC(rb_to_8s), 0);
  155. rb_define_method(rb_klass, "to_16u", RUBY_METHOD_FUNC(rb_to_16u), 0);
  156. rb_define_method(rb_klass, "to_16s", RUBY_METHOD_FUNC(rb_to_16s), 0);
  157. rb_define_method(rb_klass, "to_32s", RUBY_METHOD_FUNC(rb_to_32s), 0);
  158. rb_define_method(rb_klass, "to_32f", RUBY_METHOD_FUNC(rb_to_32f), 0);
  159. rb_define_method(rb_klass, "to_64f", RUBY_METHOD_FUNC(rb_to_64f), 0);
  160. rb_define_method(rb_klass, "vector?", RUBY_METHOD_FUNC(rb_vector_q), 0);
  161. rb_define_method(rb_klass, "square?", RUBY_METHOD_FUNC(rb_square_q), 0);
  162. rb_define_method(rb_klass, "to_CvMat", RUBY_METHOD_FUNC(rb_to_CvMat), 0);
  163. rb_define_method(rb_klass, "sub_rect", RUBY_METHOD_FUNC(rb_sub_rect), -2);
  164. rb_define_alias(rb_klass, "subrect", "sub_rect");
  165. rb_define_method(rb_klass, "slice_width", RUBY_METHOD_FUNC(rb_slice_width), 1);
  166. rb_define_method(rb_klass, "slice_height", RUBY_METHOD_FUNC(rb_slice_height), 1);
  167. rb_define_method(rb_klass, "row", RUBY_METHOD_FUNC(rb_row), -2);
  168. rb_define_method(rb_klass, "col", RUBY_METHOD_FUNC(rb_col), -2);
  169. rb_define_alias(rb_klass, "column", "col");
  170. rb_define_method(rb_klass, "each_row", RUBY_METHOD_FUNC(rb_each_row), 0);
  171. rb_define_method(rb_klass, "each_col", RUBY_METHOD_FUNC(rb_each_col), 0);
  172. rb_define_alias(rb_klass, "each_column", "each_col");
  173. rb_define_method(rb_klass, "diag", RUBY_METHOD_FUNC(rb_diag), -1);
  174. rb_define_alias(rb_klass, "diagonal", "diag");
  175. rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0);
  176. rb_define_method(rb_klass, "dims", RUBY_METHOD_FUNC(rb_dims), 0);
  177. rb_define_method(rb_klass, "dim_size", RUBY_METHOD_FUNC(rb_dim_size), 1);
  178. rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), -2);
  179. rb_define_alias(rb_klass, "at", "[]");
  180. rb_define_method(rb_klass, "[]=", RUBY_METHOD_FUNC(rb_aset), -2);
  181. rb_define_method(rb_klass, "fill", RUBY_METHOD_FUNC(rb_fill), -1);
  182. rb_define_alias(rb_klass, "set", "fill");
  183. rb_define_method(rb_klass, "fill!", RUBY_METHOD_FUNC(rb_fill_bang), -1);
  184. rb_define_alias(rb_klass, "set!", "fill!");
  185. rb_define_method(rb_klass, "clear", RUBY_METHOD_FUNC(rb_clear), 0);
  186. rb_define_alias(rb_klass, "set_zero", "clear");
  187. rb_define_method(rb_klass, "clear!", RUBY_METHOD_FUNC(rb_clear_bang), 0);
  188. rb_define_alias(rb_klass, "set_zero!", "clear!");
  189. rb_define_method(rb_klass, "identity", RUBY_METHOD_FUNC(rb_set_identity), -1);
  190. rb_define_method(rb_klass, "identity!", RUBY_METHOD_FUNC(rb_set_identity_bang), -1);
  191. rb_define_method(rb_klass, "range", RUBY_METHOD_FUNC(rb_range), -1);
  192. rb_define_method(rb_klass, "range!", RUBY_METHOD_FUNC(rb_range_bang), -1);
  193. rb_define_method(rb_klass, "reshape", RUBY_METHOD_FUNC(rb_reshape), 1);
  194. rb_define_method(rb_klass, "repeat", RUBY_METHOD_FUNC(rb_repeat), 1);
  195. rb_define_method(rb_klass, "flip", RUBY_METHOD_FUNC(rb_flip), -1);
  196. rb_define_method(rb_klass, "flip!", RUBY_METHOD_FUNC(rb_flip_bang), -1);
  197. rb_define_method(rb_klass, "split", RUBY_METHOD_FUNC(rb_split), 0);
  198. rb_define_singleton_method(rb_klass, "merge", RUBY_METHOD_FUNC(rb_merge), -2);
  199. rb_define_method(rb_klass, "rand_shuffle", RUBY_METHOD_FUNC(rb_rand_shuffle), -1);
  200. rb_define_method(rb_klass, "rand_shuffle!", RUBY_METHOD_FUNC(rb_rand_shuffle_bang), -1);
  201. rb_define_method(rb_klass, "lut", RUBY_METHOD_FUNC(rb_lut), 1);
  202. rb_define_method(rb_klass, "convert_scale", RUBY_METHOD_FUNC(rb_convert_scale), 1);
  203. rb_define_method(rb_klass, "convert_scale_abs", RUBY_METHOD_FUNC(rb_convert_scale_abs), 1);
  204. rb_define_method(rb_klass, "add", RUBY_METHOD_FUNC(rb_add), -1);
  205. rb_define_alias(rb_klass, "+", "add");
  206. rb_define_method(rb_klass, "sub", RUBY_METHOD_FUNC(rb_sub), -1);
  207. rb_define_alias(rb_klass, "-", "sub");
  208. rb_define_method(rb_klass, "mul", RUBY_METHOD_FUNC(rb_mul), -1);
  209. rb_define_method(rb_klass, "mat_mul", RUBY_METHOD_FUNC(rb_mat_mul), -1);
  210. rb_define_alias(rb_klass, "*", "mat_mul");
  211. rb_define_method(rb_klass, "div", RUBY_METHOD_FUNC(rb_div), -1);
  212. rb_define_alias(rb_klass, "/", "div");
  213. rb_define_method(rb_klass, "and", RUBY_METHOD_FUNC(rb_and), -1);
  214. rb_define_alias(rb_klass, "&", "and");
  215. rb_define_method(rb_klass, "or", RUBY_METHOD_FUNC(rb_or), -1);
  216. rb_define_alias(rb_klass, "|", "or");
  217. rb_define_method(rb_klass, "xor", RUBY_METHOD_FUNC(rb_xor), -1);
  218. rb_define_alias(rb_klass, "^", "xor");
  219. rb_define_method(rb_klass, "not", RUBY_METHOD_FUNC(rb_not), 0);
  220. rb_define_method(rb_klass, "not!", RUBY_METHOD_FUNC(rb_not_bang), 0);
  221. rb_define_method(rb_klass, "eq", RUBY_METHOD_FUNC(rb_eq), 1);
  222. rb_define_method(rb_klass, "gt", RUBY_METHOD_FUNC(rb_gt), 1);
  223. rb_define_method(rb_klass, "ge", RUBY_METHOD_FUNC(rb_ge), 1);
  224. rb_define_method(rb_klass, "lt", RUBY_METHOD_FUNC(rb_lt), 1);
  225. rb_define_method(rb_klass, "le", RUBY_METHOD_FUNC(rb_le), 1);
  226. rb_define_method(rb_klass, "ne", RUBY_METHOD_FUNC(rb_ne), 1);
  227. rb_define_method(rb_klass, "in_range", RUBY_METHOD_FUNC(rb_in_range), 2);
  228. rb_define_method(rb_klass, "abs_diff", RUBY_METHOD_FUNC(rb_abs_diff), 1);
  229. rb_define_method(rb_klass, "count_non_zero", RUBY_METHOD_FUNC(rb_count_non_zero), 0);
  230. rb_define_method(rb_klass, "sum", RUBY_METHOD_FUNC(rb_sum), 0);
  231. rb_define_method(rb_klass, "avg", RUBY_METHOD_FUNC(rb_avg), -1);
  232. rb_define_method(rb_klass, "avg_sdv", RUBY_METHOD_FUNC(rb_avg_sdv), -1);
  233. rb_define_method(rb_klass, "sdv", RUBY_METHOD_FUNC(rb_sdv), -1);
  234. rb_define_method(rb_klass, "min_max_loc", RUBY_METHOD_FUNC(rb_min_max_loc), -1);
  235. rb_define_method(rb_klass, "dot_product", RUBY_METHOD_FUNC(rb_dot_product), 1);
  236. rb_define_method(rb_klass, "cross_product", RUBY_METHOD_FUNC(rb_cross_product), 1);
  237. rb_define_method(rb_klass, "transform", RUBY_METHOD_FUNC(rb_transform), -1);
  238. rb_define_method(rb_klass, "perspective_transform", RUBY_METHOD_FUNC(rb_perspective_transform), 1);
  239. rb_define_method(rb_klass, "mul_transposed", RUBY_METHOD_FUNC(rb_mul_transposed), -2);
  240. rb_define_method(rb_klass, "trace", RUBY_METHOD_FUNC(rb_trace), 0);
  241. rb_define_method(rb_klass, "transpose", RUBY_METHOD_FUNC(rb_transpose), 0);
  242. rb_define_alias(rb_klass, "t", "transpose");
  243. rb_define_method(rb_klass, "transpose!", RUBY_METHOD_FUNC(rb_transpose_bang), 0);
  244. rb_define_alias(rb_klass, "t!", "transpose!");
  245. rb_define_method(rb_klass, "det", RUBY_METHOD_FUNC(rb_det), 0);
  246. rb_define_alias(rb_klass, "determinant", "det");
  247. rb_define_method(rb_klass, "invert", RUBY_METHOD_FUNC(rb_invert), -1);
  248. rb_define_method(rb_klass, "solve", RUBY_METHOD_FUNC(rb_solve), -1);
  249. rb_define_method(rb_klass, "svd", RUBY_METHOD_FUNC(rb_svd), -1);
  250. rb_define_method(rb_klass, "svbksb", RUBY_METHOD_FUNC(rb_svbksb), -1);
  251. rb_define_method(rb_klass, "eigenvv", RUBY_METHOD_FUNC(rb_eigenvv), -1);
  252. rb_define_method(rb_klass, "calc_covar_matrix", RUBY_METHOD_FUNC(rb_calc_covar_matrix), -1);
  253. rb_define_method(rb_klass, "mahalonobis", RUBY_METHOD_FUNC(rb_mahalonobis), -1);
  254. /* drawing function */
  255. rb_define_method(rb_klass, "line", RUBY_METHOD_FUNC(rb_line), -1);
  256. rb_define_method(rb_klass, "line!", RUBY_METHOD_FUNC(rb_line_bang), -1);
  257. rb_define_method(rb_klass, "rectangle", RUBY_METHOD_FUNC(rb_rectangle), -1);
  258. rb_define_method(rb_klass, "rectangle!", RUBY_METHOD_FUNC(rb_rectangle_bang), -1);
  259. rb_define_method(rb_klass, "circle", RUBY_METHOD_FUNC(rb_circle), -1);
  260. rb_define_method(rb_klass, "circle!", RUBY_METHOD_FUNC(rb_circle_bang), -1);
  261. rb_define_method(rb_klass, "ellipse", RUBY_METHOD_FUNC(rb_ellipse), -1);
  262. rb_define_method(rb_klass, "ellipse!", RUBY_METHOD_FUNC(rb_ellipse_bang), -1);
  263. rb_define_method(rb_klass, "ellipse_box", RUBY_METHOD_FUNC(rb_ellipse_box), -1);
  264. rb_define_method(rb_klass, "ellipse_box!", RUBY_METHOD_FUNC(rb_ellipse_box_bang), -1);
  265. rb_define_method(rb_klass, "fill_poly", RUBY_METHOD_FUNC(rb_fill_poly), -1);
  266. rb_define_method(rb_klass, "fill_poly!", RUBY_METHOD_FUNC(rb_fill_poly_bang), -1);
  267. rb_define_method(rb_klass, "fill_convex_poly", RUBY_METHOD_FUNC(rb_fill_convex_poly), -1);
  268. rb_define_method(rb_klass, "fill_convex_poly!", RUBY_METHOD_FUNC(rb_fill_convex_poly_bang), -1);
  269. rb_define_method(rb_klass, "poly_line", RUBY_METHOD_FUNC(rb_poly_line), -1);
  270. rb_define_method(rb_klass, "poly_line!", RUBY_METHOD_FUNC(rb_poly_line_bang), -1);
  271. rb_define_method(rb_klass, "put_text", RUBY_METHOD_FUNC(rb_put_text), -1);
  272. rb_define_method(rb_klass, "put_text!", RUBY_METHOD_FUNC(rb_put_text_bang), -1);
  273. rb_define_method(rb_klass, "dft", RUBY_METHOD_FUNC(rb_dft), -1);
  274. rb_define_method(rb_klass, "dct", RUBY_METHOD_FUNC(rb_dct), -1);
  275. rb_define_method(rb_klass, "sobel", RUBY_METHOD_FUNC(rb_sobel), -1);
  276. rb_define_method(rb_klass, "laplace", RUBY_METHOD_FUNC(rb_laplace), -1);
  277. rb_define_method(rb_klass, "canny", RUBY_METHOD_FUNC(rb_canny), -1);
  278. rb_define_method(rb_klass, "pre_corner_detect", RUBY_METHOD_FUNC(rb_pre_corner_detect), -1);
  279. rb_define_method(rb_klass, "corner_eigenvv", RUBY_METHOD_FUNC(rb_corner_eigenvv), -1);
  280. rb_define_method(rb_klass, "corner_min_eigen_val", RUBY_METHOD_FUNC(rb_corner_min_eigen_val), -1);
  281. rb_define_method(rb_klass, "corner_harris", RUBY_METHOD_FUNC(rb_corner_harris), -1);
  282. rb_define_private_method(rb_klass, "__find_corner_sub_pix", RUBY_METHOD_FUNC(rbi_find_corner_sub_pix), -1);
  283. rb_define_method(rb_klass, "good_features_to_track", RUBY_METHOD_FUNC(rb_good_features_to_track), -1);
  284. rb_define_method(rb_klass, "sample_line", RUBY_METHOD_FUNC(rb_sample_line), 2);
  285. rb_define_method(rb_klass, "rect_sub_pix", RUBY_METHOD_FUNC(rb_rect_sub_pix), -1);
  286. rb_define_method(rb_klass, "quadrangle_sub_pix", RUBY_METHOD_FUNC(rb_quadrangle_sub_pix), -1);
  287. rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1);
  288. rb_define_method(rb_klass, "warp_affine", RUBY_METHOD_FUNC(rb_warp_affine), -1);
  289. rb_define_singleton_method(rb_klass, "rotation_matrix2D", RUBY_METHOD_FUNC(rb_rotation_matrix2D), 3);
  290. rb_define_method(rb_klass, "warp_perspective", RUBY_METHOD_FUNC(rb_warp_perspective), -1);
  291. rb_define_singleton_method(rb_klass, "find_homography", RUBY_METHOD_FUNC(rb_find_homograpy), -1);
  292. //rb_define_method(rb_klass, "get_perspective_transform", RUBY_METHOD_FUNC(rb_get_perspective_transform), -1);
  293. //rb_define_alias(rb_klass, "warp_perspective_q_matrix", "get_perspective_transform");
  294. rb_define_method(rb_klass, "remap", RUBY_METHOD_FUNC(rb_remap), -1);
  295. //rb_define_method(rb_klass, "log_polar", RUBY_METHOD_FUNC(rb_log_polar), -1);
  296. rb_define_method(rb_klass, "erode", RUBY_METHOD_FUNC(rb_erode), -1);
  297. rb_define_method(rb_klass, "erode!", RUBY_METHOD_FUNC(rb_erode_bang), -1);
  298. rb_define_method(rb_klass, "dilate", RUBY_METHOD_FUNC(rb_dilate), -1);
  299. rb_define_method(rb_klass, "dilate!", RUBY_METHOD_FUNC(rb_dilate_bang), -1);
  300. rb_define_method(rb_klass, "morphology", RUBY_METHOD_FUNC(rb_morphology), -1);
  301. rb_define_method(rb_klass, "morphology_open", RUBY_METHOD_FUNC(rb_morphology_open), -1);
  302. rb_define_method(rb_klass, "morphology_close", RUBY_METHOD_FUNC(rb_morphology_close), -1);
  303. rb_define_method(rb_klass, "morphology_gradient", RUBY_METHOD_FUNC(rb_morphology_gradient), -1);
  304. rb_define_method(rb_klass, "morphology_tophat", RUBY_METHOD_FUNC(rb_morphology_tophat), -1);
  305. rb_define_method(rb_klass, "morphology_blackhat", RUBY_METHOD_FUNC(rb_morphology_blackhat), -1);
  306. rb_define_method(rb_klass, "smooth", RUBY_METHOD_FUNC(rb_smooth), -1);
  307. rb_define_method(rb_klass, "smooth_blur_no_scale", RUBY_METHOD_FUNC(rb_smooth_blur_no_scale), -1);
  308. rb_define_method(rb_klass, "smooth_blur", RUBY_METHOD_FUNC(rb_smooth_blur), -1);
  309. rb_define_method(rb_klass, "smooth_gaussian", RUBY_METHOD_FUNC(rb_smooth_gaussian), -1);
  310. rb_define_method(rb_klass, "smooth_median", RUBY_METHOD_FUNC(rb_smooth_median), -1);
  311. rb_define_method(rb_klass, "smooth_bilateral", RUBY_METHOD_FUNC(rb_smooth_bilateral), -1);
  312. rb_define_method(rb_klass, "filter2d", RUBY_METHOD_FUNC(rb_filter2d), -1);
  313. rb_define_method(rb_klass, "copy_make_border_constant", RUBY_METHOD_FUNC(rb_copy_make_border_constant), -1);
  314. rb_define_method(rb_klass, "copy_make_border_replicate", RUBY_METHOD_FUNC(rb_copy_make_border_replicate), -1);
  315. rb_define_method(rb_klass, "integral", RUBY_METHOD_FUNC(rb_integral), -1);
  316. rb_define_method(rb_klass, "threshold", RUBY_METHOD_FUNC(rb_threshold), -1);
  317. rb_define_method(rb_klass, "threshold_binary", RUBY_METHOD_FUNC(rb_threshold_binary), -1);
  318. rb_define_method(rb_klass, "threshold_binary_inverse", RUBY_METHOD_FUNC(rb_threshold_binary_inverse), -1);
  319. rb_define_method(rb_klass, "threshold_trunc", RUBY_METHOD_FUNC(rb_threshold_trunc), -1);
  320. rb_define_method(rb_klass, "threshold_to_zero", RUBY_METHOD_FUNC(rb_threshold_to_zero), -1);
  321. rb_define_method(rb_klass, "threshold_to_zero_inverse", RUBY_METHOD_FUNC(rb_threshold_to_zero_inverse), -1);
  322. rb_define_method(rb_klass, "pyr_down", RUBY_METHOD_FUNC(rb_pyr_down), -1);
  323. rb_define_method(rb_klass, "pyr_up", RUBY_METHOD_FUNC(rb_pyr_up), -1);
  324. rb_define_method(rb_klass, "flood_fill", RUBY_METHOD_FUNC(rb_flood_fill), -1);
  325. rb_define_method(rb_klass, "flood_fill!", RUBY_METHOD_FUNC(rb_flood_fill_bang), -1);
  326. rb_define_method(rb_klass, "find_contours", RUBY_METHOD_FUNC(rb_find_contours), -1);
  327. rb_define_method(rb_klass, "find_contours!", RUBY_METHOD_FUNC(rb_find_contours_bang), -1);
  328. rb_define_method(rb_klass, "pyr_segmentation", RUBY_METHOD_FUNC(rb_pyr_segmentation), -1);
  329. rb_define_method(rb_klass, "pyr_mean_shift_filtering", RUBY_METHOD_FUNC(rb_pyr_mean_shift_filtering), -1);
  330. rb_define_method(rb_klass, "watershed", RUBY_METHOD_FUNC(rb_watershed), 1);
  331. rb_define_method(rb_klass, "moments", RUBY_METHOD_FUNC(rb_moments), -1);
  332. rb_define_method(rb_klass, "hough_lines", RUBY_METHOD_FUNC(rb_hough_lines), -1);
  333. rb_define_method(rb_klass, "hough_lines_standard", RUBY_METHOD_FUNC(rb_hough_lines_standard), 3);
  334. rb_define_method(rb_klass, "hough_lines_probabilistic", RUBY_METHOD_FUNC(rb_hough_lines_probabilistic), 5);
  335. rb_define_method(rb_klass, "hough_lines_multi_scale", RUBY_METHOD_FUNC(rb_hough_lines_multi_scale), 5);
  336. rb_define_method(rb_klass, "hough_circles", RUBY_METHOD_FUNC(rb_hough_circles), -1);
  337. rb_define_method(rb_klass, "hough_circles_gradient", RUBY_METHOD_FUNC(rb_hough_circles_gradient), -1);
  338. //rb_define_method(rb_klass, "dist_transform", RUBY_METHOD_FUNC(rb_dist_transform), -1);
  339. rb_define_method(rb_klass, "inpaint", RUBY_METHOD_FUNC(rb_inpaint), 3);
  340. rb_define_method(rb_klass, "inpaint_ns", RUBY_METHOD_FUNC(rb_inpaint_ns), 2);
  341. rb_define_method(rb_klass, "inpaint_telea", RUBY_METHOD_FUNC(rb_inpaint_telea), 2);
  342. rb_define_method(rb_klass, "equalize_hist", RUBY_METHOD_FUNC(rb_equalize_hist), 0);
  343. rb_define_method(rb_klass, "match_template", RUBY_METHOD_FUNC(rb_match_template), -1);
  344. rb_define_method(rb_klass, "match_shapes", RUBY_METHOD_FUNC(rb_match_shapes), -1);
  345. rb_define_method(rb_klass, "match_shapes_i1", RUBY_METHOD_FUNC(rb_match_shapes_i1), -1);
  346. rb_define_method(rb_klass, "match_shapes_i2", RUBY_METHOD_FUNC(rb_match_shapes_i2), -1);
  347. rb_define_method(rb_klass, "match_shapes_i3", RUBY_METHOD_FUNC(rb_match_shapes_i3), -1);
  348. rb_define_method(rb_klass, "mean_shift", RUBY_METHOD_FUNC(rb_mean_shift), 2);
  349. rb_define_method(rb_klass, "cam_shift", RUBY_METHOD_FUNC(rb_cam_shift), 2);
  350. rb_define_method(rb_klass, "snake_image", RUBY_METHOD_FUNC(rb_snake_image), -1);
  351. rb_define_method(rb_klass, "optical_flow_hs", RUBY_METHOD_FUNC(rb_optical_flow_hs), -1);
  352. rb_define_method(rb_klass, "optical_flow_lk", RUBY_METHOD_FUNC(rb_optical_flow_lk), 2);
  353. rb_define_method(rb_klass, "optical_flow_bm", RUBY_METHOD_FUNC(rb_optical_flow_bm), -1);
  354. rb_define_singleton_method(rb_klass, "find_fundamental_mat_7point",
  355. RUBY_METHOD_FUNC(rb_find_fundamental_mat_7point), 2);
  356. rb_define_singleton_method(rb_klass, "find_fundamental_mat_8point",
  357. RUBY_METHOD_FUNC(rb_find_fundamental_mat_8point), 2);
  358. rb_define_singleton_method(rb_klass, "find_fundamental_mat_ransac",
  359. RUBY_METHOD_FUNC(rb_find_fundamental_mat_ransac), -1);
  360. rb_define_singleton_method(rb_klass, "find_fundamental_mat_lmeds",
  361. RUBY_METHOD_FUNC(rb_find_fundamental_mat_lmeds), -1);
  362. rb_define_singleton_method(rb_klass, "find_fundamental_mat",
  363. RUBY_METHOD_FUNC(rb_find_fundamental_mat), -1);
  364. rb_define_singleton_method(rb_klass, "compute_correspond_epilines",
  365. RUBY_METHOD_FUNC(rb_compute_correspond_epilines), 3);
  366. rb_define_method(rb_klass, "save_image", RUBY_METHOD_FUNC(rb_save_image), 1);
  367. }
  368. VALUE
  369. rb_allocate(VALUE klass)
  370. {
  371. return OPENCV_OBJECT(klass, 0);
  372. }
  373. /*
  374. * call-seq:
  375. * CvMat.new(<i>row, col[, depth = CV_8U][, channel = 3]</i>) -> cvmat
  376. *
  377. * Create col * row matrix. Each element set 0.
  378. *
  379. * Each element possigle range is set by <i>depth</i>. Default is unsigned 8bit.
  380. *
  381. * Number of channel is set by <i>channel</i>. <i>channel</i> should be 1..4.
  382. *
  383. */
  384. VALUE
  385. rb_initialize(int argc, VALUE *argv, VALUE self)
  386. {
  387. VALUE row, column, depth, channel;
  388. rb_scan_args(argc, argv, "22", &row, &column, &depth, &channel);
  389. DATA_PTR(self) = cvCreateMat(FIX2INT(row), FIX2INT(column),
  390. CV_MAKETYPE(CVMETHOD("DEPTH", depth, CV_8U), argc < 4 ? 3 : FIX2INT(channel)));
  391. return self;
  392. }
  393. /*
  394. * call-seq:
  395. * CvMat::load(<i>filename[,iscolor = CV_LOAD_IMAGE_COLOR]</i>)
  396. *
  397. * Load an image from file.
  398. * iscolor = CV_LOAD_IMAGE_COLOR, the loaded image is forced to be a 3-channel color image
  399. * iscolor = CV_LOAD_IMAGE_GRAYSCALE, the loaded image is forced to be grayscale
  400. * iscolor = CV_LOAD_IMAGE_UNCHANGED, the loaded image will be loaded as is.
  401. * Currently the following file format are supported.
  402. * * Windows bitmaps - BMP,DIB
  403. * * JPEG files - JPEG,JPG,JPE
  404. * * Portable Network Graphics - PNG
  405. * * Portable image format - PBM,PGM,PPM
  406. * * Sun rasters - SR,RAS
  407. * * TIFF files - TIFF,TIF
  408. */
  409. VALUE
  410. rb_load_imageM(int argc, VALUE *argv, VALUE self)
  411. {
  412. VALUE filename, iscolor;
  413. rb_scan_args(argc, argv, "11", &filename, &iscolor);
  414. Check_Type(filename, T_STRING);
  415. int _iscolor;
  416. if (TYPE(iscolor) == T_NIL) {
  417. _iscolor = CV_LOAD_IMAGE_COLOR;
  418. }
  419. else {
  420. Check_Type(iscolor, T_FIXNUM);
  421. _iscolor = FIX2INT(iscolor);
  422. }
  423. CvMat *mat;
  424. if ((mat = cvLoadImageM(StringValueCStr(filename), _iscolor)) == NULL) {
  425. rb_raise(rb_eStandardError, "file does not exist or invalid format image.");
  426. }
  427. return OPENCV_OBJECT(rb_klass, mat);
  428. }
  429. /*
  430. * nodoc
  431. */
  432. VALUE
  433. rb_method_missing(int argc, VALUE *argv, VALUE self)
  434. {
  435. /*
  436. const char *to_str = "\\Ato_(\\w+)";
  437. VALUE name, args, str[3], method;
  438. rb_scan_args(argc, argv, "1*", &name, &args);
  439. if (RARRAY_LEN(args) != 0)
  440. return rb_call_super(argc, argv);
  441. if(rb_reg_match(rb_reg_new(to_str, strlen(to_str), 0), rb_funcall(name, rb_intern("to_s"), 0)) == Qnil)
  442. return rb_call_super(argc, argv);
  443. str[0] = rb_str_new2("%s2%s");
  444. str[1] = rb_color_model(self);
  445. str[2] = rb_reg_nth_match(1, rb_backref_get());
  446. method = rb_f_sprintf(3, str);
  447. if (rb_respond_to(rb_module_opencv(), rb_intern(StringValuePtr(method))))
  448. return rb_funcall(rb_module_opencv(), rb_intern(StringValuePtr(method)), 1, self);
  449. return rb_call_super(argc, argv);
  450. */
  451. VALUE name, args, method;
  452. rb_scan_args(argc, argv, "1*", &name, &args);
  453. method = rb_funcall(name, rb_intern("to_s"), 0);
  454. if (RARRAY_LEN(args) != 0 || !rb_respond_to(rb_module_opencv(), rb_intern(StringValuePtr(method))))
  455. return rb_call_super(argc, argv);
  456. return rb_funcall(rb_module_opencv(), rb_intern(StringValuePtr(method)), 1, self);
  457. }
  458. /*
  459. * call-seq:
  460. * to_s -> string
  461. *
  462. * Return following string.
  463. * m = CvMat.new(100, 100, :cv8u, 3)
  464. * m.to_s # => <CvMat:100x100,depth=cv8u,channel=3>
  465. */
  466. VALUE
  467. rb_to_s(VALUE self)
  468. {
  469. const int i = 6;
  470. VALUE str[i];
  471. str[0] = rb_str_new2("<%s:%dx%d,depth=%s,channel=%d>");
  472. str[1] = rb_str_new2(rb_class2name(CLASS_OF(self)));
  473. str[2] = rb_width(self);
  474. str[3] = rb_height(self);
  475. str[4] = rb_depth(self);
  476. str[5] = rb_channel(self);
  477. return rb_f_sprintf(i, str);
  478. }
  479. /*
  480. * call-seq:
  481. * has_parent? -> true or false
  482. *
  483. * Return <tt>true</tt> if this matrix has parent object, otherwise <tt>false</tt>.
  484. */
  485. VALUE
  486. rb_has_parent_q(VALUE self)
  487. {
  488. return lookup_root_object(CVMAT(self)) ? Qtrue : Qfalse;
  489. }
  490. /*
  491. * call-seq:
  492. * parent -> obj or nil
  493. *
  494. * Return root object that refer this object.
  495. */
  496. VALUE
  497. rb_parent(VALUE self)
  498. {
  499. VALUE root = lookup_root_object(CVMAT(self));
  500. return root ? root : Qnil;
  501. }
  502. /*
  503. * call-seq:
  504. * inside?(obj) -> true or false
  505. *
  506. *
  507. */
  508. VALUE
  509. rb_inside_q(VALUE self, VALUE object)
  510. {
  511. if (cCvPoint::rb_compatible_q(cCvPoint::rb_class(), object)) {
  512. CvMat *mat = CVMAT(self);
  513. int x = NUM2INT(rb_funcall(object, rb_intern("x"), 0));
  514. int y = NUM2INT(rb_funcall(object, rb_intern("y"), 0));
  515. if (cCvRect::rb_compatible_q(cCvRect::rb_class(), object)) {
  516. int width = NUM2INT(rb_funcall(object, rb_intern("width"), 0));
  517. int height = NUM2INT(rb_funcall(object, rb_intern("height"), 0));
  518. return x >= 0 && y >= 0 && x < mat->width && x + width < mat->width && y < mat->height && y + height < mat->height ? Qtrue : Qfalse;
  519. } else {
  520. return x >= 0 && y >= 0 && x < mat->width && y < mat->height ? Qtrue : Qfalse;
  521. }
  522. }
  523. rb_raise(rb_eArgError, "argument 1 should have method \"x\", \"y\"");
  524. }
  525. /*
  526. * call-seq:
  527. * to_IplConvKernel -> iplconvkernel
  528. *
  529. * Create IplConvKernel from this matrix.
  530. */
  531. VALUE
  532. rb_to_IplConvKernel(VALUE self, VALUE anchor)
  533. {
  534. CvMat *src = CVMAT(self);
  535. CvPoint p = VALUE_TO_CVPOINT(anchor);
  536. IplConvKernel *kernel = cvCreateStructuringElementEx(src->cols, src->rows, p.x, p.y, CV_SHAPE_CUSTOM, src->data.i);
  537. return DEPEND_OBJECT(cIplConvKernel::rb_class(), kernel, self);
  538. }
  539. /*
  540. * call-seq:
  541. * create_mask -> cvmat(single-channel 8bit unsinged image)
  542. *
  543. * Create single-channel 8bit unsinged image that filled 0.
  544. */
  545. VALUE
  546. rb_create_mask(VALUE self)
  547. {
  548. VALUE mask = cCvMat::new_object(cvGetSize(CVARR(self)), CV_8UC1);
  549. cvZero(CVARR(self));
  550. return mask;
  551. }
  552. /*
  553. * call-seq:
  554. * width -> int
  555. *
  556. * Return number of columns.
  557. */
  558. VALUE
  559. rb_width(VALUE self)
  560. {
  561. return INT2FIX(CVMAT(self)->width);
  562. }
  563. /*
  564. * call-seq:
  565. * height -> int
  566. *
  567. * Return number of rows.
  568. */
  569. VALUE
  570. rb_height(VALUE self)
  571. {
  572. return INT2FIX(CVMAT(self)->height);
  573. }
  574. /*
  575. * call-seq:
  576. * depth -> symbol
  577. *
  578. * Return depth symbol. (see OpenCV::DEPTH)
  579. */
  580. VALUE
  581. rb_depth(VALUE self)
  582. {
  583. return rb_hash_aref(rb_funcall(rb_const_get(rb_module_opencv(), rb_intern("DEPTH")), rb_intern("invert"), 0), INT2FIX(CV_MAT_DEPTH(CVMAT(self)->type)));
  584. }
  585. /*
  586. * call-seq:
  587. * channel -> int (1 < channel < 4)
  588. *
  589. * Return number of channel.
  590. */
  591. VALUE
  592. rb_channel(VALUE self)
  593. {
  594. return INT2FIX(CV_MAT_CN(CVMAT(self)->type));
  595. }
  596. /*
  597. * call-seq:
  598. * data -> binary (by String class)
  599. *
  600. * Return raw data of matrix.
  601. */
  602. VALUE
  603. rb_data(VALUE self)
  604. {
  605. IplImage *image = IPLIMAGE(self);
  606. return rb_str_new((char *)image->imageData, image->imageSize);
  607. }
  608. /*
  609. * call-seq:
  610. * clone -> cvmat
  611. *
  612. * Clone matrix. The parent and child relation is not succeeded.
  613. * Instance-specific method is succeeded.
  614. *
  615. * module M
  616. * def example
  617. * true
  618. * end
  619. * end
  620. *
  621. * mat.extend M
  622. * mat.example #=> true
  623. * clone = mat.clone
  624. * clone.example #=> true
  625. * copy = mat.copy
  626. * copy.example #=> raise NoMethodError
  627. */
  628. VALUE
  629. rb_clone(VALUE self)
  630. {
  631. VALUE clone = rb_obj_clone(self);
  632. DATA_PTR(clone) = cvClone(CVARR(self));
  633. return clone;
  634. }
  635. /*
  636. * call-seq:
  637. * copy() -> cvmat
  638. * copy(<i>mat</i>) -> mat
  639. * copy(<i>val</i>) -> array(include cvmat)
  640. *
  641. * Copy matrix. The parent and child relation is not succeeded.
  642. * Instance-specific method is *NOT* succeeded. see also #clone.
  643. *
  644. * There are 3 kind behavior depending on the argument.
  645. *
  646. * copy()
  647. * Return one copied matrix.
  648. * copy(mat)
  649. * Copy own elements to target matrix. Return nil.
  650. * Size (or ROI) and channel and depth should be match.
  651. * If own width or height does not match target matrix, raise CvUnmatchedSizes
  652. * If own channel or depth does not match target matrix, raise CvUnmatchedFormats
  653. * copy(val)
  654. * The amounts of the specified number are copied. Return Array with copies.
  655. * If you give the 0 or negative value. Return nil.
  656. * mat.copy(3) #=> [mat1, mat2, mat3]
  657. * mat.copy(-1) #=> nil
  658. *
  659. * When not apply to any, raise ArgumentError
  660. */
  661. VALUE
  662. rb_copy(int argc, VALUE *argv, VALUE self)
  663. {
  664. VALUE value, copied, tmp;
  665. CvMat *src = CVMAT(self);
  666. rb_scan_args(argc, argv, "01", &value);
  667. if (argc == 0) {
  668. CvSize size = cvGetSize(src);
  669. copied = new_object(cvGetSize(src), cvGetElemType(src));
  670. cvCopy(src, CVMAT(copied));
  671. return copied;
  672. }else{
  673. if (rb_obj_is_kind_of(value, rb_klass)) {
  674. cvCopy(src, CVMAT(value));
  675. return Qnil;
  676. }else if (rb_obj_is_kind_of(value, rb_cFixnum)) {
  677. int n = FIX2INT(value);
  678. if (n > 0) {
  679. copied = rb_ary_new2(n);
  680. for (int i = 0; i < n; i++) {
  681. tmp = new_object(src->rows, src->cols, cvGetElemType(src));
  682. cvCopy(src, CVMAT(tmp));
  683. rb_ary_store(copied, i, tmp);
  684. }
  685. return copied;
  686. }else{
  687. return Qnil;
  688. }
  689. }else
  690. rb_raise(rb_eArgError, "");
  691. }
  692. }
  693. VALUE
  694. copy(VALUE mat)
  695. {
  696. CvMat *src = CVMAT(mat);
  697. VALUE copied = new_object(cvGetSize(src), cvGetElemType(src));
  698. cvCopy(src, CVMAT(copied));
  699. return copied;
  700. }
  701. /*
  702. * call-seq:
  703. * to_8u -> cvmat(depth = CV_8U)
  704. *
  705. * Return the new matrix that elements is converted to unsigned 8bit.
  706. */
  707. VALUE
  708. rb_to_8u(VALUE self)
  709. {
  710. CvMat *src = CVMAT(self);
  711. VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_8U, CV_MAT_CN(src->type)));
  712. cvConvert(src, CVMAT(dest));
  713. return dest;
  714. }
  715. /*
  716. * call-seq:
  717. * to_8s -> cvmat(depth = CV_8S)
  718. *
  719. * Return the new matrix that elements is converted to signed 8bit.
  720. */
  721. VALUE
  722. rb_to_8s(VALUE self)
  723. {
  724. CvMat *src = CVMAT(self);
  725. VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_8S, CV_MAT_CN(src->type)));
  726. cvConvert(src, CVMAT(dest));
  727. return dest;
  728. }
  729. /*
  730. * call-seq:
  731. * to_16u -> cvmat(depth = CV_16U)
  732. *
  733. * Return the new matrix that elements is converted to unsigned 16bit.
  734. */
  735. VALUE rb_to_16u(VALUE self)
  736. {
  737. CvMat *src = CVMAT(self);
  738. VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_16U, CV_MAT_CN(src->type)));
  739. cvConvert(src, CVMAT(dest));
  740. return dest;
  741. }
  742. /*
  743. * call-seq:
  744. * to_16s -> cvmat(depth = CV_16s)
  745. *
  746. * Return the new matrix that elements is converted to signed 16bit.
  747. */
  748. VALUE
  749. rb_to_16s(VALUE self)
  750. {
  751. CvMat *src = CVMAT(self);
  752. VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_16S, CV_MAT_CN(src->type)));
  753. cvConvert(src, CVMAT(dest));
  754. return dest;
  755. }
  756. /*
  757. * call-seq:
  758. * to_32s -> cvmat(depth = CV_32S)
  759. *
  760. * Return the new matrix that elements is converted to signed 32bit.
  761. */
  762. VALUE
  763. rb_to_32s(VALUE self)
  764. {
  765. CvMat *src = CVMAT(self);
  766. VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_32S, CV_MAT_CN(src->type)));
  767. cvConvert(src, CVMAT(dest));
  768. return dest;
  769. }
  770. /*
  771. * call-seq:
  772. * to_32f -> cvmat(depth = CV_32F)
  773. *
  774. * Return the new matrix that elements is converted to 32bit floating-point.
  775. */
  776. VALUE
  777. rb_to_32f(VALUE self)
  778. {
  779. CvMat *src = CVMAT(self);
  780. VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_32F, CV_MAT_CN(src->type)));
  781. cvConvert(src, CVMAT(dest));
  782. return dest;
  783. }
  784. /*
  785. * call-seq:
  786. * to_64F -> cvmat(depth = CV_64F)
  787. *
  788. * Return the new matrix that elements is converted to 64bit floating-point.
  789. */
  790. VALUE
  791. rb_to_64f(VALUE self)
  792. {
  793. CvMat *src = CVMAT(self);
  794. VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_64F, CV_MAT_CN(src->type)));
  795. cvConvert(src, CVMAT(dest));
  796. return dest;
  797. }
  798. /*
  799. * call-seq:
  800. * vector? -> true or false
  801. *
  802. * If #width or #height is 1, return true. Otherwise return false.
  803. */
  804. VALUE
  805. rb_vector_q(VALUE self)
  806. {
  807. CvMat *mat = CVMAT(self);
  808. return (mat->width == 1|| mat->height == 1) ? Qtrue : Qfalse;
  809. }
  810. /*
  811. * call-seq:
  812. * square? -> true or false
  813. *
  814. * If #width == #height return true. Otherwise return false.
  815. */
  816. VALUE
  817. rb_square_q(VALUE self)
  818. {
  819. CvMat *mat = CVMAT(self);
  820. return mat->width == mat->height ? Qtrue : Qfalse;
  821. }
  822. /************************************************************
  823. cxcore function
  824. ************************************************************/
  825. /*
  826. * Return CvMat object with reference to caller-object.
  827. *
  828. * src = CvMat.new(10, 10)
  829. * src.has_parent? #=> false
  830. * src.parent #=> nil
  831. * mat = src.to_CvMat
  832. * mat.has_parent? #=> true
  833. * mat.parent #=> CvMat object "src"
  834. *
  835. * This case, 'src' is root-object. and 'mat' is child-object refer to 'src'.
  836. * src <=refer= mat
  837. * In C, 'src->data' and 'mat->data' is common. Therefore, they cause the change each other.
  838. * object 'src' don't GC.
  839. */
  840. VALUE
  841. rb_to_CvMat(VALUE self)
  842. {
  843. return DEPEND_OBJECT(rb_klass, cvGetMat(CVARR(self), CVALLOC(CvMat)), self);
  844. }
  845. /*
  846. * call-seq:
  847. * sub_rect(<i>rect</i>) -> cvmat
  848. * sub_rect(<i>topleft</i>, <i>size</i>) -> cvmat
  849. * sub_rect(<i>x, y, width, height</i>) -> cvmat
  850. *
  851. * Return parts of self as CvMat.
  852. *
  853. * <i>p</i> or <i>x</i>,<i>y</i> mean top-left coordinate.
  854. * <i>size</i> or <i>width</i>,<i>height</i> is size.
  855. *
  856. * link:../images/CvMat_sub_rect.png
  857. */
  858. VALUE
  859. rb_sub_rect(VALUE self, VALUE args)
  860. {
  861. CvRect area;
  862. CvPoint topleft;
  863. CvSize size;
  864. switch(RARRAY_LEN(args)) {
  865. case 1:
  866. area = VALUE_TO_CVRECT(RARRAY_PTR(args)[0]);
  867. break;
  868. case 2:
  869. topleft = VALUE_TO_CVPOINT(RARRAY_PTR(args)[0]);
  870. size = VALUE_TO_CVSIZE(RARRAY_PTR(args)[1]);
  871. area.x = topleft.x;
  872. area.y = topleft.y;
  873. area.width = size.width;
  874. area.height = size.height;
  875. break;
  876. case 4:
  877. area.x = NUM2INT(RARRAY_PTR(args)[0]);
  878. area.y = NUM2INT(RARRAY_PTR(args)[1]);
  879. area.width = NUM2INT(RARRAY_PTR(args)[2]);
  880. area.height = NUM2INT(RARRAY_PTR(args)[3]);
  881. break;
  882. default:
  883. rb_raise(rb_eArgError, "wrong number of arguments (%ld of 1 or 2 or 4)", RARRAY_LEN(args));
  884. }
  885. return DEPEND_OBJECT(rb_klass,
  886. cvGetSubRect(CVARR(self), CVALLOC(CvMat), area),
  887. self);
  888. }
  889. /*
  890. * call-seq:
  891. * slice_width(<i>n</i>)
  892. *
  893. * The matrix is divided into <i>n</i> piece by the width.
  894. * If it cannot be just divided, warning is displayed.
  895. *
  896. * e.g.
  897. * m = OpenCV::CvMat.new(10, 10) #=> size 10x10 matrix
  898. * ml, mr = m.slice_width(2) #=> 5x10 and 5x10 matrix
  899. *
  900. * ml, mm, mr = m.slice_width(3)#=> 3x10 3x10 3x10 matrix
  901. * warning : width does not div correctly.
  902. */
  903. VALUE
  904. rb_slice_width(VALUE self, VALUE num)
  905. {
  906. int n = NUM2INT(num);
  907. if (n < 1) {rb_raise(rb_eArgError, "number of piece should be > 0");}
  908. CvSize size = cvGetSize(CVARR(self));
  909. if (size.width % n != 0) {rb_warn("width does not div correctly.");}
  910. int div_x = size.width / n;
  911. VALUE ary = rb_ary_new2(n);
  912. for (int i = 0; i < n; i++) {
  913. CvRect rect = {div_x * i, 0, div_x, size.height};
  914. rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), CVALLOC(CvMat), rect), self));
  915. }
  916. return ary;
  917. }
  918. /*
  919. * call-seq:
  920. * slice_height(<i>n</i>)
  921. *
  922. * The matrix is divided into <i>n</i> piece by the height.
  923. * If it cannot be just divided, warning is displayed.
  924. *
  925. * see also #slice_width.
  926. */
  927. VALUE
  928. rb_slice_height(VALUE self, VALUE num)
  929. {
  930. int n = NUM2INT(num);
  931. if (n < 1) {rb_raise(rb_eArgError, "number of piece should be > 0");}
  932. CvSize size = cvGetSize(CVARR(self));
  933. if (size.height % n != 0) {rb_warn("height does not div correctly.");}
  934. int div_y = size.height / n;
  935. VALUE ary = rb_ary_new2(n);
  936. for (int i = 0; i < n; i++) {
  937. CvRect rect = {0, div_y * i, size.width, div_y};
  938. rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), CVALLOC(CvMat), rect), self));
  939. }
  940. return ary;
  941. }
  942. /*
  943. * call-seq:
  944. * row(<i>n</i>) -> Return row
  945. * row(<i>n1, n2, ...</i>) -> Return Array of row
  946. *
  947. * Return row(or rows) of matrix.
  948. * argument should be Fixnum or CvSlice compatible object.
  949. */
  950. VALUE
  951. rb_row(VALUE self, VALUE args)
  952. {
  953. int len = RARRAY_LEN(args);
  954. if (len < 1) {rb_raise(rb_eArgError, "wrong number of argument.(more than 1)");}
  955. VALUE ary = rb_ary_new2(len);
  956. for (int i = 0; i < len; i++) {
  957. VALUE value = rb_ary_entry(args, i);
  958. if (FIXNUM_P(value)) {
  959. rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), CVALLOC(CvMat), FIX2INT(value)), self));
  960. }else{
  961. CvSlice slice = VALUE_TO_CVSLICE(value);
  962. rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRows(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self));
  963. }
  964. }
  965. return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0);
  966. }
  967. /*
  968. * call-seq:
  969. * col(<i>n</i>) -> Return column
  970. * col(<i>n1, n2, ...</i>) -> Return Array of columns
  971. *
  972. * Return column(or columns) of matrix.
  973. * argument should be Fixnum or CvSlice compatible object.
  974. */
  975. VALUE
  976. rb_col(VALUE self, VALUE args)
  977. {
  978. int len = RARRAY_LEN(args);
  979. if (len < 1) {rb_raise(rb_eArgError, "wrong number of argument.(more than 1)");}
  980. VALUE ary = rb_ary_new2(len);
  981. for (int i = 0; i < len; i++) {
  982. VALUE value = rb_ary_entry(args, i);
  983. if (FIXNUM_P(value)) {
  984. rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), CVALLOC(CvMat), FIX2INT(value)), self));
  985. }else{
  986. CvSlice slice = VALUE_TO_CVSLICE(value);
  987. rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCols(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self));
  988. }
  989. }
  990. return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0);
  991. }
  992. /*
  993. * call-seq:
  994. * each_row{|row| ... } -> self
  995. *
  996. * Calls block once for each row in self, passing that element as a parameter.
  997. *
  998. * see also CvMat#each_col
  999. */
  1000. VALUE
  1001. rb_each_row(VALUE self)
  1002. {
  1003. int rows = CVMAT(self)->rows;
  1004. for (int i = 0; i < rows; i++) {
  1005. rb_yield(DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), CVALLOC(CvMat), i), self));
  1006. }
  1007. return self;
  1008. }
  1009. /*
  1010. * call-seq:
  1011. * each_col{|col| ... } -> self
  1012. *
  1013. * Calls block once for each column in self, passing that element as a parameter.
  1014. *
  1015. * see also CvMat#each_row
  1016. */
  1017. VALUE
  1018. rb_each_col(VALUE self)
  1019. {
  1020. int cols = CVMAT(self)->cols;
  1021. for (int i = 0; i < cols; i++) {
  1022. rb_yield(DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), CVALLOC(CvMat), i), self));
  1023. }
  1024. return self;
  1025. }
  1026. /*
  1027. * call-seq:
  1028. * diag(<i>[val = 0]</i>) -> cvmat
  1029. *
  1030. * Return one of array diagonals.
  1031. * <i>val</i> is zeo corresponds to the main diagonal, -1 corresponds to the diagonal above the main etc, 1 corresponds to the diagonal below the main etc.
  1032. *
  1033. */
  1034. VALUE
  1035. rb_diag(int argc, VALUE *argv, VALUE self)
  1036. {
  1037. VALUE val;
  1038. if (rb_scan_args(argc, argv, "01", &val) < 1) {
  1039. val = INT2FIX(0);
  1040. }
  1041. return DEPEND_OBJECT(rb_klass, cvGetDiag(CVARR(self), CVALLOC(CvMat), NUM2INT(val)), self);
  1042. }
  1043. /*
  1044. * call-seq:
  1045. * size -> cvsize
  1046. *
  1047. * Return size by CvSize
  1048. */
  1049. VALUE
  1050. rb_size(VALUE self)
  1051. {
  1052. return cCvSize::new_object(cvGetSize(CVARR(self)));
  1053. }
  1054. /*
  1055. VALUE rb_elem_type(VALUE self) {
  1056. return INT2FIX(cvGetElemType(CVARR(self)));
  1057. }
  1058. */
  1059. /*
  1060. * call-seq:
  1061. * dims -> array(int, int, ...)
  1062. *
  1063. * Return number of array dimensions and their sizes or the size of particular dimension.
  1064. * In case of CvMat it always returns 2 regardless of number of matrix rows.
  1065. */
  1066. VALUE
  1067. rb_dims(VALUE self)
  1068. {
  1069. int size[CV_MAX_DIM];
  1070. int dims = cvGetDims(CVARR(self), size);
  1071. VALUE ary = rb_ary_new2(dims);
  1072. for (int i = 0; i < dims; i++) {
  1073. rb_ary_store(ary, i, INT2FIX(size[i]));
  1074. }
  1075. return ary;
  1076. }
  1077. /*
  1078. * call-seq:
  1079. * dim_size(<i>index</i>) -> int
  1080. *
  1081. * Return number of dimension.
  1082. * almost same as CvMat#dims[<i>index</i>].
  1083. * If the dimension specified with index doesn't exist, CvStatusOutOfRange raise.
  1084. */
  1085. VALUE
  1086. rb_dim_size(VALUE self, VALUE index)
  1087. {
  1088. return INT2FIX(cvGetDimSize(CVARR(self), FIX2INT(index)));
  1089. }
  1090. /*
  1091. * call-seq:
  1092. * [<i>idx1[,idx2]...</i>]
  1093. *
  1094. * Return value of the particular array element as CvScalar.
  1095. */
  1096. VALUE
  1097. rb_aref(VALUE self, VALUE args)
  1098. {
  1099. int index[CV_MAX_DIM];
  1100. for (int i = 0; i < RARRAY_LEN(args); i++) {
  1101. index[i] = NUM2INT(rb_ary_entry(args, i));
  1102. }
  1103. CvScalar scalar = cvScalarAll(0);
  1104. switch(RARRAY_LEN(args)) {
  1105. case 1:
  1106. scalar = cvGet1D(CVARR(self), index[0]);
  1107. break;
  1108. case 2:
  1109. scalar = cvGet2D(CVARR(self), index[0], index[1]);
  1110. break;
  1111. default:
  1112. scalar = cvGetND(CVARR(self), index);
  1113. }
  1114. return cCvScalar::new_object(scalar);
  1115. }
  1116. /*
  1117. * call-seq:
  1118. * [<i>idx1[,idx2]...</i>] = <i>value</i>
  1119. *
  1120. * Set value of the particular array element to <i>value</i>.
  1121. * <i>value</i> should be CvScalar.
  1122. */
  1123. VALUE
  1124. rb_aset(VALUE self, VALUE args)
  1125. {
  1126. CvScalar scalar = VALUE_TO_CVSCALAR(rb_ary_pop(args));
  1127. int index[CV_MAX_DIM];
  1128. for (int i = 0; i < RARRAY_LEN(args); i++) {
  1129. index[i] = NUM2INT(rb_ary_entry(args, i));
  1130. }
  1131. switch(RARRAY_LEN(args)) {
  1132. case 1:
  1133. cvSet1D(CVARR(self), index[0], scalar);
  1134. break;
  1135. case 2:
  1136. cvSet2D(CVARR(self), index[0], index[1], scalar);
  1137. break;
  1138. default:
  1139. cvSetND(CVARR(self), index, scalar);
  1140. }
  1141. return self;
  1142. }
  1143. /*
  1144. * call-seq:
  1145. * fill(<i>value[, mask]</i>) -> cvmat
  1146. *
  1147. * Return CvMat copied value to every selected element. value should be CvScalar or compatible object.
  1148. * self[I] = value if mask(I)!=0
  1149. *
  1150. * note: This method support ROI on IplImage class. but COI not support. COI should not be set.
  1151. * image = IplImage.new(10, 20) #=> create 3 channel image.
  1152. * image.coi = 1 #=> set COI
  1153. * image.fill(CvScalar.new(10, 20, 30)) #=> raise CvBadCOI error.
  1154. */
  1155. VALUE
  1156. rb_fill(int argc, VALUE *argv, VALUE self)
  1157. {
  1158. return rb_fill_bang(argc, argv, copy(self));
  1159. }
  1160. /*
  1161. * call-seq:
  1162. * fill!(<i>value[, mask]</i>) -> self
  1163. *
  1164. * Copie value to every selected element.
  1165. * self[I] = value if mask(I)!=0
  1166. *
  1167. * see also #fill.
  1168. */
  1169. VALUE
  1170. rb_fill_bang(int argc, VALUE *argv, VALUE self)
  1171. {
  1172. VALUE value, mask;
  1173. rb_scan_args(argc, argv, "11", &value, &mask);
  1174. cvSet(CVARR(self), VALUE_TO_CVSCALAR(value), MASK(mask));
  1175. return self;
  1176. }
  1177. /*
  1178. * call-seq:
  1179. * save_image(<i>filename</i>) -> self
  1180. *
  1181. * Saves an image to file. The image format is chosen depending on the filename extension.
  1182. * Only 8bit single-channel or 3-channel(with 'BGR' channel order) image can be saved.
  1183. *
  1184. * e.g.
  1185. * image = OpenCV::CvMat.new(10, 10, CV_8U, 3)
  1186. * image.save_image("image.jpg") #=> save as JPEG format
  1187. * image.save_image("image.png") #=> save as PNG format
  1188. */
  1189. VALUE
  1190. rb_save_image(VALUE self, VALUE filename)
  1191. {
  1192. Check_Type(filename, T_STRING);
  1193. cvSaveImage(StringValueCStr(filename), CVARR(self));
  1194. return self;
  1195. }
  1196. /*
  1197. * call-seq:
  1198. * clear -> cvmat
  1199. *
  1200. * Return new matrix all element-value cleared.
  1201. */
  1202. VALUE
  1203. rb_clear(VALUE self)
  1204. {
  1205. return rb_clear_bang(copy(self));
  1206. }
  1207. /*
  1208. * call-seq:
  1209. * clear! -> self
  1210. *
  1211. * Clear all element-value. Return self.
  1212. */
  1213. VALUE
  1214. rb_clear_bang(VALUE self)
  1215. {
  1216. cvSetZero(CVARR(self));
  1217. return self;
  1218. }
  1219. /*
  1220. * call-seq:
  1221. * identity(<i>[val = [1]]</i>) -> cvmat
  1222. *
  1223. * Return initializes scaled identity matrix.
  1224. * <i>val</i> should be CvScalar.
  1225. *
  1226. * arr(i, j) = val if i = j, 0 otherwise
  1227. */
  1228. VALUE
  1229. rb_set_identity(int argc, VALUE *argv, VALUE self)
  1230. {
  1231. return rb_set_identity_bang(argc, argv, copy(self));
  1232. }
  1233. /*
  1234. * call-seq:
  1235. * identity!(<i>[val = [1]]</i>) -> self
  1236. *
  1237. * Initialize scaled identity matrix.
  1238. * <i>val</i> should be CvScalar.
  1239. *
  1240. * arr(i, j) = val if i = j, 0 otherwise
  1241. */
  1242. VALUE
  1243. rb_set_identity_bang(int argc, VALUE *argv, VALUE self)
  1244. {
  1245. VALUE val;
  1246. CvScalar value;
  1247. if (rb_scan_args(argc, argv, "01", &val) < 1) {
  1248. value = cvRealScalar(1);
  1249. }else{
  1250. value = VALUE_TO_CVSCALAR(val);
  1251. }
  1252. cvSetIdentity(CVARR(self), value);
  1253. return self;
  1254. }
  1255. /*
  1256. * call-seq:
  1257. * range(start, end) -> cvmat
  1258. *
  1259. * Create and return filled matrix with given range of numbers.
  1260. *
  1261. * see range!
  1262. */
  1263. VALUE
  1264. rb_range(int argc, VALUE *argv, VALUE self)
  1265. {
  1266. return rb_range_bang(argc, argv, copy(self));
  1267. }
  1268. /*
  1269. * call-seq:
  1270. * range!(start, end) -> self
  1271. *
  1272. * Fills matrix with given range of numbers.
  1273. *
  1274. * in…