mirror of
https://github.com/ruby-opencv/ruby-opencv
synced 2023-03-27 23:22:12 -04:00
added CvHistogram functions
This commit is contained in:
parent
503209160d
commit
e3cad86f0a
6 changed files with 692 additions and 52 deletions
|
@ -35,27 +35,125 @@ define_ruby_class()
|
|||
* note: this comment is used by rdoc.
|
||||
*/
|
||||
VALUE opencv = rb_module_opencv();
|
||||
|
||||
rb_klass = rb_define_class_under(opencv, "CvHistogram", rb_cObject);
|
||||
|
||||
|
||||
rb_define_alloc_func(rb_klass, rb_allocate);
|
||||
rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
|
||||
rb_define_method(rb_klass, "is_uniform?", RUBY_METHOD_FUNC(rb_is_uniform), 0);
|
||||
rb_define_method(rb_klass, "is_sparse?", RUBY_METHOD_FUNC(rb_is_sparse), 0);
|
||||
rb_define_method(rb_klass, "has_range?", RUBY_METHOD_FUNC(rb_has_range), 0);
|
||||
rb_define_method(rb_klass, "dims", RUBY_METHOD_FUNC(rb_dims), 0);
|
||||
rb_define_method(rb_klass, "calc_hist", RUBY_METHOD_FUNC(rb_calc_hist), -1);
|
||||
rb_define_method(rb_klass, "calc_hist!", RUBY_METHOD_FUNC(rb_calc_hist_bang), -1);
|
||||
rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), -2);
|
||||
rb_define_alias(rb_klass, "query_hist_value", "[]");
|
||||
rb_define_method(rb_klass, "min_max_value", RUBY_METHOD_FUNC(rb_min_max_value), 0);
|
||||
rb_define_method(rb_klass, "copy_hist", RUBY_METHOD_FUNC(rb_copy_hist), 0);
|
||||
|
||||
rb_define_method(rb_klass, "normalize", RUBY_METHOD_FUNC(rb_normalize), 1);
|
||||
rb_define_method(rb_klass, "normalize!", RUBY_METHOD_FUNC(rb_normalize_bang), 1);
|
||||
rb_define_method(rb_klass, "thresh", RUBY_METHOD_FUNC(rb_thresh), 1);
|
||||
rb_define_alias(rb_klass, "threshold", "thresh");
|
||||
rb_define_method(rb_klass, "thresh!", RUBY_METHOD_FUNC(rb_thresh_bang), 1);
|
||||
rb_define_alias(rb_klass, "threshold!", "thresh!");
|
||||
rb_define_method(rb_klass, "clear_hist", RUBY_METHOD_FUNC(rb_clear_hist), 0);
|
||||
rb_define_alias(rb_klass, "clear", "clear_hist");
|
||||
rb_define_method(rb_klass, "clear_hist!", RUBY_METHOD_FUNC(rb_clear_hist_bang), 0);
|
||||
rb_define_alias(rb_klass, "clear!", "clear_hist!");
|
||||
|
||||
rb_define_method(rb_klass, "normalize_hist", RUBY_METHOD_FUNC(rb_normalize_hist), 1);
|
||||
rb_define_alias(rb_klass, "normalize", "normalize_hist");
|
||||
rb_define_method(rb_klass, "normalize_hist!", RUBY_METHOD_FUNC(rb_normalize_hist_bang), 1);
|
||||
rb_define_alias(rb_klass, "normalize!", "normalize_hist!");
|
||||
|
||||
rb_define_method(rb_klass, "thresh_hist", RUBY_METHOD_FUNC(rb_thresh_hist), 1);
|
||||
rb_define_alias(rb_klass, "thresh", "thresh_hist");
|
||||
rb_define_method(rb_klass, "thresh_hist!", RUBY_METHOD_FUNC(rb_thresh_hist_bang), 1);
|
||||
rb_define_alias(rb_klass, "thresh!", "thresh_hist!");
|
||||
|
||||
rb_define_method(rb_klass, "set_hist_bin_ranges", RUBY_METHOD_FUNC(rb_set_hist_bin_ranges), -1);
|
||||
rb_define_method(rb_klass, "set_hist_bin_ranges!", RUBY_METHOD_FUNC(rb_set_hist_bin_ranges_bang), -1);
|
||||
|
||||
rb_define_method(rb_klass, "calc_back_project", RUBY_METHOD_FUNC(rb_calc_back_project), 1);
|
||||
rb_define_method(rb_klass, "calc_back_project_patch", RUBY_METHOD_FUNC(rb_calc_back_project_patch), 4);
|
||||
|
||||
rb_define_singleton_method(rb_klass, "calc_prob_density", RUBY_METHOD_FUNC(rb_calc_prob_density), -1);
|
||||
rb_define_singleton_method(rb_klass, "compare_hist", RUBY_METHOD_FUNC(rb_compare_hist), 3);
|
||||
}
|
||||
|
||||
void
|
||||
release_hist(void* ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
try {
|
||||
cvReleaseHist((CvHistogram**)&ptr);
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_allocate(VALUE klass)
|
||||
{
|
||||
CvHistogram* ptr;
|
||||
return Data_Make_Struct(klass, CvHistogram, 0, -1, ptr);
|
||||
CvHistogram* ptr = NULL;
|
||||
return Data_Wrap_Struct(klass, 0, release_hist, ptr);
|
||||
}
|
||||
|
||||
float*
|
||||
ary2fltptr(VALUE ary, float* buff)
|
||||
{
|
||||
Check_Type(ary, T_ARRAY);
|
||||
int size = RARRAY_LEN(ary);
|
||||
VALUE* ary_ptr = RARRAY_PTR(ary);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
buff[i] = NUM2DBL(ary_ptr[i]);
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
|
||||
int*
|
||||
ary2intptr(VALUE ary, int* buff)
|
||||
{
|
||||
Check_Type(ary, T_ARRAY);
|
||||
int size = RARRAY_LEN(ary);
|
||||
VALUE* ary_ptr = RARRAY_PTR(ary);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
buff[i] = NUM2INT(ary_ptr[i]);
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE _dims, _sizes, _type, _ranges, _uniform;
|
||||
int dims, type, uniform;
|
||||
int* sizes;
|
||||
float** ranges = NULL;
|
||||
|
||||
rb_scan_args(argc, argv, "32", &_dims, &_sizes, &_type, &_ranges, &_uniform);
|
||||
int sizes_len = RARRAY_LEN(_sizes);
|
||||
sizes = ALLOCA_N(int, sizes_len);
|
||||
|
||||
if (NIL_P(_ranges)) {
|
||||
sizes = ary2intptr(_sizes, sizes);
|
||||
ranges = NULL;
|
||||
}
|
||||
else {
|
||||
ranges = ALLOCA_N(float*, sizes_len);
|
||||
VALUE* range_ptr = RARRAY_PTR(_ranges);
|
||||
int i;
|
||||
for (i = 0; i < sizes_len; i++) {
|
||||
sizes[i] = NUM2INT(RARRAY_PTR(_sizes)[i]);
|
||||
ranges[i] = ary2fltptr(range_ptr[i], ALLOCA_N(float, 2));
|
||||
}
|
||||
}
|
||||
uniform = TRUE_OR_FALSE(_uniform, 1);
|
||||
|
||||
try {
|
||||
DATA_PTR(self) = cvCreateHist(NUM2INT(_dims), sizes, NUM2INT(_type), ranges, uniform);
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -90,6 +188,103 @@ rb_has_range(VALUE self)
|
|||
return CV_HIST_HAS_RANGES(CVHISTOGRAM(self)) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_calc_hist(int argc, VALUE* argv, VALUE self)
|
||||
{
|
||||
return rb_calc_hist_bang(argc, argv, rb_copy_hist(self));
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_calc_hist_bang(int argc, VALUE* argv, VALUE self)
|
||||
{
|
||||
VALUE images, accumulate, mask;
|
||||
rb_scan_args(argc, argv, "12", &images, &accumulate, &mask);
|
||||
Check_Type(images, T_ARRAY);
|
||||
int num_images = RARRAY_LEN(images);
|
||||
IplImage** img = ALLOCA_N(IplImage*, num_images);
|
||||
VALUE* images_ptr = RARRAY_PTR(images);
|
||||
for (int i = 0; i < num_images; i++) {
|
||||
img[i] = IPLIMAGE_WITH_CHECK(images_ptr[i]);
|
||||
}
|
||||
CvMat* m = NIL_P(mask) ? NULL : CVMAT_WITH_CHECK(mask);
|
||||
try {
|
||||
cvCalcHist(img, CVHISTOGRAM(self), TRUE_OR_FALSE(accumulate, 0), m);
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* [<i>idx1[,idx2]...</i>]
|
||||
*/
|
||||
VALUE
|
||||
rb_aref(VALUE self, VALUE args)
|
||||
{
|
||||
int num_idx = RARRAY_LEN(args);
|
||||
int* idx = ALLOCA_N(int, num_idx);
|
||||
VALUE* args_ptr = RARRAY_PTR(args);
|
||||
for (int i = 0; i < num_idx; i++) {
|
||||
idx[i] = NUM2INT(args_ptr[i]);
|
||||
}
|
||||
|
||||
float value = 0.0;
|
||||
CvHistogram* self_ptr = CVHISTOGRAM(self);
|
||||
try {
|
||||
switch (num_idx) {
|
||||
case 1:
|
||||
value = cvQueryHistValue_1D(self_ptr, idx[0]);
|
||||
break;
|
||||
case 2:
|
||||
value = cvQueryHistValue_2D(self_ptr, idx[0], idx[1]);
|
||||
break;
|
||||
case 3:
|
||||
value = cvQueryHistValue_3D(self_ptr, idx[0], idx[1], idx[2]);
|
||||
break;
|
||||
default:
|
||||
value = cvQueryHistValue_nD(self_ptr, idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return rb_float_new((double)value);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_min_max_value(VALUE self)
|
||||
{
|
||||
CvHistogram* self_ptr = CVHISTOGRAM(self);
|
||||
int dims = 0;
|
||||
float min_value = 0.0, max_value = 0.0;
|
||||
int *min_idx = NULL;
|
||||
int *max_idx = NULL;
|
||||
try {
|
||||
dims = cvGetDims(self_ptr->bins, NULL);
|
||||
min_idx = ALLOCA_N(int, dims);
|
||||
max_idx = ALLOCA_N(int, dims);
|
||||
cvGetMinMaxHistValue(CVHISTOGRAM(self), &min_value, &max_value, min_idx, max_idx);
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
VALUE _min_idx = rb_ary_new2(dims);
|
||||
VALUE _max_idx = rb_ary_new2(dims);
|
||||
for (int i = 0; i < dims; i++) {
|
||||
rb_ary_store(_min_idx, i, INT2NUM(min_idx[i]));
|
||||
rb_ary_store(_max_idx, i, INT2NUM(max_idx[i]));
|
||||
}
|
||||
|
||||
return rb_ary_new3(4, rb_float_new((double)min_value), rb_float_new((double)max_value),
|
||||
_min_idx, _max_idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* dims -> [int[,int...]]
|
||||
|
@ -97,60 +292,59 @@ rb_has_range(VALUE self)
|
|||
VALUE
|
||||
rb_dims(VALUE self)
|
||||
{
|
||||
VALUE result = Qnil;
|
||||
VALUE _sizes = Qnil;
|
||||
int size[CV_MAX_DIM];
|
||||
int dims = 0;
|
||||
try {
|
||||
int dims = cvGetDims(CVHISTOGRAM(self)->bins, size);
|
||||
result = rb_ary_new2(dims);
|
||||
for(int i = 0; i < dims; ++i){
|
||||
rb_ary_store(result, i, INT2NUM(size[i]));
|
||||
dims = cvGetDims(CVHISTOGRAM(self)->bins, size);
|
||||
_sizes = rb_ary_new2(dims);
|
||||
for (int i = 0; i < dims; ++i) {
|
||||
rb_ary_store(_sizes, i, INT2NUM(size[i]));
|
||||
}
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
return result;
|
||||
return rb_assoc_new(INT2NUM(dims), _sizes);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* bins -> cvmatnd or cvsparsemat
|
||||
*/
|
||||
VALUE
|
||||
rb_bins(VALUE self)
|
||||
{
|
||||
CvHistogram *hist = CVHISTOGRAM(self);
|
||||
return REFER_OBJECT(CV_IS_SPARSE_HIST(hist) ? cCvSparseMat::rb_class() : cCvMatND::rb_class(), hist->bins, self);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* copy -> cvhist
|
||||
* copy_hist -> cvhist
|
||||
*
|
||||
* Clone histogram.
|
||||
*/
|
||||
VALUE
|
||||
rb_copy(VALUE self)
|
||||
rb_copy_hist(VALUE self)
|
||||
{
|
||||
VALUE dest = 0;
|
||||
CvHistogram *hist = CVHISTOGRAM(dest);
|
||||
CvHistogram* hist = NULL;
|
||||
try {
|
||||
cvCopyHist(CVHISTOGRAM(self), &hist);
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
return dest;
|
||||
return Data_Wrap_Struct(rb_klass, 0, release_hist, hist);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* clear!
|
||||
* clear_hist
|
||||
*/
|
||||
VALUE
|
||||
rb_clear_hist(VALUE self)
|
||||
{
|
||||
return rb_clear_hist_bang(rb_copy_hist(self));
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* clear_hist!
|
||||
*
|
||||
* Sets all histogram bins to 0 in case of dense histogram and removes all histogram bins in case of sparse array.
|
||||
*/
|
||||
VALUE
|
||||
rb_clear_bang(VALUE self)
|
||||
rb_clear_hist_bang(VALUE self)
|
||||
{
|
||||
try {
|
||||
cvClearHist(CVHISTOGRAM(self));
|
||||
|
@ -168,9 +362,9 @@ rb_clear_bang(VALUE self)
|
|||
* Return normalized the histogram bins by scaling them, such that the sum of the bins becomes equal to <i>factor</i>.
|
||||
*/
|
||||
VALUE
|
||||
rb_normalize(VALUE self, VALUE factor)
|
||||
rb_normalize_hist(VALUE self, VALUE factor)
|
||||
{
|
||||
return rb_normalize_bang(rb_copy(self), factor);
|
||||
return rb_normalize_hist_bang(rb_copy_hist(self), factor);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -180,7 +374,7 @@ rb_normalize(VALUE self, VALUE factor)
|
|||
* normalizes the histogram bins by scaling them, such that the sum of the bins becomes equal to <i>factor</i>.
|
||||
*/
|
||||
VALUE
|
||||
rb_normalize_bang(VALUE self, VALUE factor)
|
||||
rb_normalize_hist_bang(VALUE self, VALUE factor)
|
||||
{
|
||||
try {
|
||||
cvNormalizeHist(CVHISTOGRAM(self), NUM2DBL(factor));
|
||||
|
@ -193,27 +387,27 @@ rb_normalize_bang(VALUE self, VALUE factor)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* thresh(<i>factor</i>) -> cvhist
|
||||
* thresh_hist(<i>threshold</i>) -> cvhist
|
||||
*
|
||||
* Return cleared histogram bins that are below the specified threshold.
|
||||
*/
|
||||
VALUE
|
||||
rb_thresh(VALUE self, VALUE factor)
|
||||
rb_thresh_hist(VALUE self, VALUE threshold)
|
||||
{
|
||||
return rb_thresh_bang(rb_copy(self), factor);
|
||||
return rb_thresh_hist_bang(rb_copy_hist(self), threshold);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* thresh!(<i>factor</i>) -> self
|
||||
* thresh_hist!(<i>threshold</i>) -> self
|
||||
*
|
||||
* Cleares histogram bins that are below the specified threshold.
|
||||
*/
|
||||
VALUE
|
||||
rb_thresh_bang(VALUE self, VALUE factor)
|
||||
rb_thresh_hist_bang(VALUE self, VALUE threshold)
|
||||
{
|
||||
try {
|
||||
cvThreshHist(CVHISTOGRAM(self), NUM2DBL(factor));
|
||||
cvThreshHist(CVHISTOGRAM(self), NUM2DBL(threshold));
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
|
@ -221,5 +415,132 @@ rb_thresh_bang(VALUE self, VALUE factor)
|
|||
return self;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_set_hist_bin_ranges(int argc, VALUE* argv, VALUE self)
|
||||
{
|
||||
return rb_set_hist_bin_ranges_bang(argc, argv, rb_copy_hist(self));
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_set_hist_bin_ranges_bang(int argc, VALUE* argv, VALUE self)
|
||||
{
|
||||
VALUE _ranges, _uniform;
|
||||
rb_scan_args(argc, argv, "11", &_ranges, &_uniform);
|
||||
Check_Type(_ranges, T_ARRAY);
|
||||
|
||||
int ranges_size = RARRAY_LEN(_ranges);
|
||||
float** ranges = ALLOCA_N(float*, ranges_size);
|
||||
VALUE* range_ptr = RARRAY_PTR(_ranges);
|
||||
for (int i = 0; i < ranges_size; ++i) {
|
||||
ranges[i] = ary2fltptr(range_ptr[i], ALLOCA_N(float, 2));
|
||||
}
|
||||
int uniform = TRUE_OR_FALSE(_uniform, 1);
|
||||
|
||||
try {
|
||||
cvSetHistBinRanges(CVHISTOGRAM(self), ranges, uniform);
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_calc_back_project(VALUE self, VALUE image)
|
||||
{
|
||||
Check_Type(image, T_ARRAY);
|
||||
int num_images = RARRAY_LEN(image);
|
||||
if (num_images == 0) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
IplImage** img = ALLOCA_N(IplImage*, num_images);
|
||||
VALUE* image_ptr = RARRAY_PTR(image);
|
||||
for (int i = 0; i < num_images; ++i) {
|
||||
img[i] = IPLIMAGE_WITH_CHECK(image_ptr[i]);
|
||||
}
|
||||
|
||||
CvSize size;
|
||||
size.width = img[0]->width;
|
||||
size.height = img[0]->height;
|
||||
VALUE back_project = cCvMat::new_mat_kind_object(size, image_ptr[0]);
|
||||
try {
|
||||
cvCalcBackProject(img, CVARR(back_project), CVHISTOGRAM(self));
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return back_project;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_calc_back_project_patch(VALUE self, VALUE image, VALUE patch_size, VALUE method, VALUE factor)
|
||||
{
|
||||
Check_Type(image, T_ARRAY);
|
||||
int num_images = RARRAY_LEN(image);
|
||||
if (num_images == 0) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
IplImage** img = ALLOCA_N(IplImage*, num_images);
|
||||
VALUE* image_ptr = RARRAY_PTR(image);
|
||||
for (int i = 0; i < num_images; ++i) {
|
||||
img[i] = IPLIMAGE_WITH_CHECK(image_ptr[i]);
|
||||
}
|
||||
|
||||
CvSize patchsize = VALUE_TO_CVSIZE(patch_size);
|
||||
CvSize dst_size;
|
||||
dst_size.width = img[0]->width - patchsize.width + 1;
|
||||
dst_size.height = img[0]->height - patchsize.height + 1;
|
||||
|
||||
VALUE dst = cCvMat::new_mat_kind_object(dst_size, image_ptr[0], CV_32F, 1);
|
||||
try {
|
||||
cvCalcBackProjectPatch(img, CVARR(dst), patchsize, CVHISTOGRAM(self),
|
||||
NUM2INT(method), NUM2DBL(factor));
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_compare_hist(VALUE self, VALUE hist1, VALUE hist2, VALUE method)
|
||||
{
|
||||
double result = 0;
|
||||
try {
|
||||
result = cvCompareHist(CVHISTOGRAM_WITH_CHECK(hist1), CVHISTOGRAM_WITH_CHECK(hist2),
|
||||
NUM2INT(method));
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return rb_float_new(result);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_calc_prob_density(int argc, VALUE* argv, VALUE self)
|
||||
{
|
||||
VALUE hist1, hist2, scale;
|
||||
rb_scan_args(argc, argv, "21", &hist1, &hist2, &scale);
|
||||
double s = NIL_P(scale) ? 255 : NUM2DBL(scale);
|
||||
|
||||
CvHistogram* hist1_ptr = CVHISTOGRAM_WITH_CHECK(hist1);
|
||||
VALUE dst_hist = rb_allocate(rb_klass);
|
||||
try {
|
||||
cvCopyHist(hist1_ptr, (CvHistogram**)&(DATA_PTR(dst_hist)));
|
||||
cvCalcProbDensity(hist1_ptr, CVHISTOGRAM_WITH_CHECK(hist2), CVHISTOGRAM(dst_hist), s);
|
||||
}
|
||||
catch (cv::Exception& e) {
|
||||
raise_cverror(e);
|
||||
}
|
||||
|
||||
return dst_hist;
|
||||
}
|
||||
|
||||
__NAMESPACE_END_CVHISTOGRAM
|
||||
__NAMESPACE_END_OPENCV
|
||||
|
|
|
@ -19,33 +19,55 @@ __NAMESPACE_BEGIN_OPENCV
|
|||
__NAMESPACE_BEGIN_CVHISTOGRAM
|
||||
|
||||
VALUE rb_class();
|
||||
|
||||
VALUE rb_allocate(VALUE klass);
|
||||
void define_ruby_class();
|
||||
|
||||
VALUE rb_initialize(int argc, VALUE *argv, VALUE self);
|
||||
VALUE rb_is_uniform(VALUE self);
|
||||
VALUE rb_is_sparse(VALUE self);
|
||||
VALUE rb_has_range(VALUE self);
|
||||
VALUE rb_calc_hist(int argc, VALUE* argv, VALUE self);
|
||||
VALUE rb_calc_hist_bang(int argc, VALUE* argv, VALUE self);
|
||||
VALUE rb_aref(VALUE self, VALUE args);
|
||||
VALUE rb_min_max_value(VALUE self);
|
||||
VALUE rb_dims(VALUE self);
|
||||
VALUE rb_bins(VALUE self);
|
||||
VALUE rb_copy_hist(VALUE self);
|
||||
|
||||
VALUE rb_clear(VALUE self);
|
||||
VALUE rb_clear_bang(VALUE self);
|
||||
VALUE rb_clear_hist(VALUE self);
|
||||
VALUE rb_clear_hist_bang(VALUE self);
|
||||
|
||||
VALUE rb_normalize(VALUE self, VALUE factor);
|
||||
VALUE rb_normalize_bang(VALUE self, VALUE factor);
|
||||
VALUE rb_thresh(VALUE self, VALUE factor);
|
||||
VALUE rb_thresh_bang(VALUE self, VALUE factor);
|
||||
VALUE rb_normalize_hist(VALUE self, VALUE factor);
|
||||
VALUE rb_normalize_hist_bang(VALUE self, VALUE factor);
|
||||
VALUE rb_thresh_hist(VALUE self, VALUE threshold);
|
||||
VALUE rb_thresh_hist_bang(VALUE self, VALUE threshold);
|
||||
|
||||
VALUE rb_set_hist_bin_ranges(int argc, VALUE* argv, VALUE self);
|
||||
VALUE rb_set_hist_bin_ranges_bang(int argc, VALUE* argv, VALUE self);
|
||||
|
||||
VALUE rb_calc_back_project(VALUE self, VALUE image);
|
||||
VALUE rb_calc_back_project_patch(VALUE self, VALUE image, VALUE patch_size, VALUE method, VALUE factor);
|
||||
|
||||
VALUE rb_compare_hist(VALUE self, VALUE hist1, VALUE hist2, VALUE method);
|
||||
VALUE rb_calc_prob_density(int argc, VALUE* argv, VALUE self);
|
||||
|
||||
__NAMESPACE_END_CVHISTOGRAM
|
||||
|
||||
inline CvHistogram*
|
||||
CVHISTOGRAM(VALUE object)
|
||||
{
|
||||
CvHistogram *ptr;
|
||||
CvHistogram* ptr;
|
||||
Data_Get_Struct(object, CvHistogram, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline CvHistogram*
|
||||
CVHISTOGRAM_WITH_CHECK(VALUE object)
|
||||
{
|
||||
if (!rb_obj_is_kind_of(object, cCvHistogram::rb_class()))
|
||||
raise_typeerror(object, cCvHistogram::rb_class());
|
||||
return CVHISTOGRAM(object);
|
||||
}
|
||||
|
||||
__NAMESPACE_END_OPENCV
|
||||
|
||||
#endif // RUBY_OPENCV_CVHISTOGRAM_H
|
||||
|
|
|
@ -282,6 +282,18 @@ define_ruby_module()
|
|||
rb_define_const(rb_module, "CV_SVD_MODIFY_A", INT2FIX(CV_SVD_MODIFY_A));
|
||||
rb_define_const(rb_module, "CV_SVD_U_T", INT2FIX(CV_SVD_U_T));
|
||||
rb_define_const(rb_module, "CV_SVD_V_T", INT2FIX(CV_SVD_V_T));
|
||||
|
||||
/* Histogram representation format */
|
||||
rb_define_const(rb_module, "CV_HIST_ARRAY", INT2FIX(CV_HIST_ARRAY));
|
||||
rb_define_const(rb_module, "CV_HIST_SPARSE", INT2FIX(CV_HIST_SPARSE));
|
||||
rb_define_const(rb_module, "CV_HIST_TREE", INT2FIX(CV_HIST_TREE));
|
||||
rb_define_const(rb_module, "CV_HIST_UNIFORM", INT2FIX(CV_HIST_UNIFORM));
|
||||
|
||||
/* Histogram comparison method */
|
||||
rb_define_const(rb_module, "CV_COMP_CORREL", INT2FIX(CV_COMP_CORREL));
|
||||
rb_define_const(rb_module, "CV_COMP_CHISQR", INT2FIX(CV_COMP_CHISQR));
|
||||
rb_define_const(rb_module, "CV_COMP_INTERSECT", INT2FIX(CV_COMP_INTERSECT));
|
||||
rb_define_const(rb_module, "CV_COMP_BHATTACHARYYA", INT2FIX(CV_COMP_BHATTACHARYYA));
|
||||
|
||||
VALUE inversion_method = rb_hash_new();
|
||||
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */
|
||||
|
|
|
@ -9,6 +9,8 @@ class OpenCVTestCase < Test::Unit::TestCase
|
|||
SAMPLE_DIR = File.expand_path(File.dirname(__FILE__)) + '/samples/'
|
||||
FILENAME_CAT = SAMPLE_DIR + 'cat.jpg'
|
||||
FILENAME_LENA256x256 = SAMPLE_DIR + 'lena-256x256.jpg'
|
||||
FILENAME_LENA32x32 = SAMPLE_DIR + 'lena-32x32.jpg'
|
||||
FILENAME_LENA_EYES = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-eyes.jpg'
|
||||
FILENAME_FRUITS = SAMPLE_DIR + 'fruits.jpg'
|
||||
HAARCASCADE_FRONTALFACE_ALT = SAMPLE_DIR + 'haarcascade_frontalface_alt.xml.gz'
|
||||
AVI_SAMPLE = SAMPLE_DIR + 'movie_sample.avi'
|
||||
|
|
271
test/test_cvhistogram.rb
Executable file
271
test/test_cvhistogram.rb
Executable file
|
@ -0,0 +1,271 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- mode: ruby; coding: utf-8-unix -*-
|
||||
require 'test/unit'
|
||||
require 'opencv'
|
||||
require File.expand_path(File.dirname(__FILE__)) + '/helper'
|
||||
|
||||
include OpenCV
|
||||
|
||||
# Tests for OpenCV::CvHistogram
|
||||
class TestCvHistogram < OpenCVTestCase
|
||||
def setup
|
||||
@img = IplImage.load(FILENAME_LENA32x32, 0)
|
||||
|
||||
dim = 1
|
||||
sizes = [8]
|
||||
ranges = [[0, 255]]
|
||||
@hist1 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges, true).calc_hist!([@img])
|
||||
|
||||
dim = 2
|
||||
sizes = [8, 16]
|
||||
ranges = [[0, 255], [0, 255]]
|
||||
@hist2 = CvHistogram.new(dim, sizes, CV_HIST_SPARSE, ranges, true).calc_hist!([@img, @img])
|
||||
end
|
||||
|
||||
def teardown
|
||||
@hist1 = nil
|
||||
@hist2 = nil
|
||||
GC.start
|
||||
end
|
||||
|
||||
def test_initialize
|
||||
dim = 1
|
||||
sizes = [256]
|
||||
ranges = [[0, 256]]
|
||||
hist1 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges, true)
|
||||
hist2 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY)
|
||||
hist3 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, nil)
|
||||
hist4 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, nil, false)
|
||||
end
|
||||
|
||||
def test_is_uniform
|
||||
assert(@hist1.is_uniform?)
|
||||
assert(@hist2.is_uniform?)
|
||||
end
|
||||
|
||||
def test_is_sparse
|
||||
assert_false(@hist1.is_sparse?)
|
||||
assert(@hist2.is_sparse?)
|
||||
end
|
||||
|
||||
def test_has_range
|
||||
assert(@hist1.has_range?)
|
||||
assert(@hist2.has_range?)
|
||||
end
|
||||
|
||||
def test_calc_hist
|
||||
img = IplImage.new(1, 1, :cv8u, 1)
|
||||
assert_equal(CvHistogram, @hist1.calc_hist([img]).class)
|
||||
assert_equal(CvHistogram, @hist1.calc_hist([img, img]).class)
|
||||
assert_equal(CvHistogram, @hist1.calc_hist([img], true).class)
|
||||
assert_equal(CvHistogram, @hist1.calc_hist([img, img], false).class)
|
||||
mask = CvMat.new(1, 1, :cv8u, 1)
|
||||
assert_equal(CvHistogram, @hist1.calc_hist([img], true, mask).class)
|
||||
|
||||
assert_raise(TypeError) {
|
||||
@hist1.calc_hist(img)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
@hist1.calc_hist([DUMMY_OBJ])
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
@hist1.calc_hist(nil)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
@hist1.calc_hist([img], true, DUMMY_OBJ)
|
||||
}
|
||||
assert_raise(CvStsBadArg) {
|
||||
@hist1.calc_hist([])
|
||||
}
|
||||
end
|
||||
|
||||
def test_aref
|
||||
expected = [0.0, 102.0, 189.0, 244.0, 285.0, 140.0, 64.0, 0.0]
|
||||
expected.each_with_index { |x, i|
|
||||
assert_in_delta(x, @hist1[i], 0.001)
|
||||
assert_in_delta(x, @hist1.query_hist_value(i), 0.001)
|
||||
}
|
||||
end
|
||||
|
||||
def test_min_max_value
|
||||
min, max, min_loc, max_loc = @hist1.min_max_value
|
||||
assert_in_delta(0.0, min, 0.001)
|
||||
assert_in_delta(285.0, max, 0.001)
|
||||
assert_equal(Array, min_loc.class)
|
||||
assert_equal(Array, max_loc.class)
|
||||
assert_equal(1, min_loc.size)
|
||||
assert_equal(1, max_loc.size)
|
||||
assert_equal(0, min_loc[0])
|
||||
assert_equal(4, max_loc[0])
|
||||
|
||||
min, max, min_loc, max_loc = @hist2.min_max_value
|
||||
assert_in_delta(14.0, min, 0.001)
|
||||
assert_in_delta(158.0, max, 0.001)
|
||||
assert_equal(Array, min_loc.class)
|
||||
assert_equal(Array, max_loc.class)
|
||||
assert_equal(2, min_loc.size)
|
||||
assert_equal(2, max_loc.size)
|
||||
assert_equal(1, min_loc[0])
|
||||
assert_equal(2, min_loc[1])
|
||||
assert_equal(4, max_loc[0])
|
||||
assert_equal(9, max_loc[1])
|
||||
end
|
||||
|
||||
def test_dims
|
||||
dims, sizes = @hist1.dims
|
||||
assert_equal(1, dims)
|
||||
assert_equal(Array, sizes.class)
|
||||
assert_equal(1, sizes.size)
|
||||
assert_equal(8, sizes[0])
|
||||
|
||||
dims, sizes = @hist2.dims
|
||||
assert_equal(2, dims)
|
||||
assert_equal(Array, sizes.class)
|
||||
assert_equal(2, sizes.size)
|
||||
assert_equal(8, sizes[0])
|
||||
assert_equal(16, sizes[1])
|
||||
end
|
||||
|
||||
def test_copy_hist
|
||||
expected = [0.0, 102.0, 189.0, 244.0, 285.0, 140.0, 64.0, 0.0]
|
||||
hist = @hist1.copy_hist
|
||||
expected.each_with_index { |x, i|
|
||||
assert_in_delta(x, hist[i], 0.001)
|
||||
assert_in_delta(x, hist.query_hist_value(i), 0.001)
|
||||
}
|
||||
end
|
||||
|
||||
def test_clear_hist
|
||||
@hist1.clear_hist!
|
||||
dims, sizes = @hist1.dims
|
||||
dims.times { |i|
|
||||
assert_in_delta(0.0, @hist1[i], 0.001)
|
||||
}
|
||||
end
|
||||
|
||||
def test_normalize_hist
|
||||
@hist1.normalize_hist!(100)
|
||||
expected = [0.0, 9.96, 18.46, 23.83, 27.83, 13.67, 6.25, 0.0]
|
||||
expected.each_with_index { |x, i|
|
||||
assert_in_delta(x, @hist1[i], 0.01)
|
||||
}
|
||||
end
|
||||
|
||||
def test_thresh_hist
|
||||
@hist1.thresh_hist!(150)
|
||||
expected = [0.0, 0.0, 189.0, 244.0, 285.0, 0.0, 0.0, 0.0]
|
||||
expected.each_with_index { |x, i|
|
||||
assert_in_delta(x, @hist1[i], 0.001)
|
||||
}
|
||||
end
|
||||
|
||||
def test_set_hist_bin_ranges
|
||||
dim = 1
|
||||
sizes = [8]
|
||||
|
||||
hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY)
|
||||
assert_false(hist.has_range?)
|
||||
assert(hist.is_uniform?)
|
||||
|
||||
ranges = [[0, 255]]
|
||||
hist.set_hist_bin_ranges!(ranges, true)
|
||||
assert(hist.has_range?)
|
||||
assert(hist.is_uniform?)
|
||||
|
||||
assert_raise(TypeError) {
|
||||
hist.set_hist_bin_ranges!(DUMMY_OBJ)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
hist.set_hist_bin_ranges!([DUMMY_OBJ])
|
||||
}
|
||||
end
|
||||
|
||||
def test_calc_back_project
|
||||
back_project = @hist1.calc_back_project([@img])
|
||||
assert_equal(@img.class, back_project.class)
|
||||
assert_equal('2a0097af1ab4f9343e4feaae3a780c93', hash_img(back_project))
|
||||
|
||||
assert_raise(TypeError) {
|
||||
@hist1.calc_back_project(DUMMY_OBJ)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
@hist1.calc_back_project([DUMMY_OBJ])
|
||||
}
|
||||
end
|
||||
|
||||
def test_calc_back_project_patch
|
||||
img = IplImage.load(FILENAME_LENA256x256, 0)
|
||||
template = IplImage.load(FILENAME_LENA_EYES, 0)
|
||||
|
||||
dim = 1
|
||||
sizes = [8]
|
||||
ranges = [[0, 255]]
|
||||
hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges).calc_hist!([template])
|
||||
back_project = hist.calc_back_project_patch([img], template.size, CV_COMP_CORREL, 1.0)
|
||||
assert_equal('e6497e45c6f2f715328bbc2fefe31581', hash_img(back_project))
|
||||
|
||||
assert_raise(TypeError) {
|
||||
hist.calc_back_project_patch(DUMMY_OBJ, template.size, CV_COMP_CORREL, 1.0)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
hist.calc_back_project_patch([DUMMY_OBJ], template.size, CV_COMP_CORREL, 1.0)
|
||||
}
|
||||
|
||||
# Uncomment the following line to show the result
|
||||
# min_val, max_val, min_loc, max_loc = back_project.min_max_loc
|
||||
# result = img.rectangle(max_loc, CvPoint.new(max_loc.x + template.width, max_loc.y + template.height),
|
||||
# :thickness => 2)
|
||||
# snap img, template, back_project, result
|
||||
end
|
||||
|
||||
def test_compare_hist
|
||||
img = IplImage.load(FILENAME_CAT, 0)
|
||||
dim, sizes = @hist1.dims
|
||||
ranges = [[0, 255]]
|
||||
hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges).calc_hist!([img])
|
||||
|
||||
assert_in_delta(0.7446, CvHistogram.compare_hist(@hist1, hist, CV_COMP_CORREL), 0.001)
|
||||
assert_in_delta(184459.0, CvHistogram.compare_hist(@hist1, hist, CV_COMP_CHISQR), 1.0)
|
||||
assert_in_delta(1024.0, CvHistogram.compare_hist(@hist1, hist, CV_COMP_INTERSECT), 1.0)
|
||||
assert_in_delta(0.2955, CvHistogram.compare_hist(@hist1, hist, CV_COMP_BHATTACHARYYA), 0.001)
|
||||
|
||||
assert_raise(TypeError) {
|
||||
CvHistogram.compare_hist(DUMMY_OBJ, hist, CV_COMP_CORREL)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
CvHistogram.compare_hist(@hist1, DUMMY_OBJ, CV_COMP_CORREL)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
CvHistogram.compare_hist(@hist1, hist, DUMMY_OBJ)
|
||||
}
|
||||
end
|
||||
|
||||
def test_calc_prob_density
|
||||
img = IplImage.load(FILENAME_CAT, 0)
|
||||
dim, sizes = @hist1.dims
|
||||
ranges = [[0, 255]]
|
||||
hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges).calc_hist!([img])
|
||||
dst = CvHistogram.calc_prob_density(hist, @hist1)
|
||||
|
||||
assert_equal(CvHistogram, dst.class)
|
||||
dim, sizes = dst.dims
|
||||
expected_dim, expected_sizes = @hist1.dims
|
||||
assert_equal(expected_dim, dim)
|
||||
expected_sizes.each_with_index { |x, i|
|
||||
assert_equal(x, sizes[i])
|
||||
}
|
||||
|
||||
expected = [0.0, 1.437, 1.135, 1.092, 2.323, 3.712, 3.103, 0.0]
|
||||
expected.each_with_index { |x, i|
|
||||
assert_in_delta(x, dst[i], 0.001)
|
||||
}
|
||||
|
||||
assert_raise(TypeError) {
|
||||
CvHistogram.calc_prob_density(DUMMY_OBJ, @hist1)
|
||||
}
|
||||
assert_raise(TypeError) {
|
||||
CvHistogram.calc_prob_density(hist, DUMMY_OBJ)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -124,6 +124,18 @@ class TestOpenCV < OpenCVTestCase
|
|||
assert_equal(1, CV_SVD_MODIFY_A)
|
||||
assert_equal(2, CV_SVD_U_T)
|
||||
assert_equal(4, CV_SVD_V_T)
|
||||
|
||||
# Histogram representation format
|
||||
assert_equal(0, CV_HIST_ARRAY)
|
||||
assert_equal(1, CV_HIST_SPARSE)
|
||||
assert_equal(1, CV_HIST_TREE)
|
||||
assert_equal(1, CV_HIST_UNIFORM)
|
||||
|
||||
# Histogram comparison method
|
||||
assert_equal(0, CV_COMP_CORREL)
|
||||
assert_equal(1, CV_COMP_CHISQR)
|
||||
assert_equal(2, CV_COMP_INTERSECT)
|
||||
assert_equal(3, CV_COMP_BHATTACHARYYA)
|
||||
end
|
||||
|
||||
def test_symbols
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue