mirror of
https://github.com/ruby-opencv/ruby-opencv
synced 2023-03-27 23:22:12 -04:00
implemented and tested CvHuMoments
This commit is contained in:
parent
9e79d09e74
commit
13ccfb5257
5 changed files with 269 additions and 0 deletions
133
ext/cvhumoments.cpp
Normal file
133
ext/cvhumoments.cpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/************************************************************
|
||||
|
||||
cvhumoments.cpp -
|
||||
|
||||
$Author: ser1zw $
|
||||
|
||||
Copyright (C) 2011 ser1zw
|
||||
|
||||
************************************************************/
|
||||
#include "cvhumoments.h"
|
||||
|
||||
/*
|
||||
* Document-class: OpenCV::CvHuMoments
|
||||
*
|
||||
* moments
|
||||
*/
|
||||
__NAMESPACE_BEGIN_OPENCV
|
||||
__NAMESPACE_BEGIN_CVHUMOMENTS
|
||||
|
||||
#define DEFINE_CVHUMOMENTS_GETTER(elem) \
|
||||
rb_define_method(rb_klass, #elem, RUBY_METHOD_FUNC(rb_##elem), 0)
|
||||
|
||||
#define CVHUMOMENTS_GETTER(elem) \
|
||||
VALUE rb_##elem(VALUE self) { return DBL2NUM(CVHUMOMENTS(self)->elem); }
|
||||
|
||||
VALUE rb_klass;
|
||||
|
||||
VALUE
|
||||
rb_class()
|
||||
{
|
||||
return rb_klass;
|
||||
}
|
||||
|
||||
void
|
||||
define_ruby_class()
|
||||
{
|
||||
if (rb_klass)
|
||||
return;
|
||||
/*
|
||||
* opencv = rb_define_module("OpenCV");
|
||||
*
|
||||
* note: this comment is used by rdoc.
|
||||
*/
|
||||
VALUE opencv = rb_module_opencv();
|
||||
|
||||
rb_klass = rb_define_class_under(opencv, "CvHuMoments", 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, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0);
|
||||
rb_define_alias(rb_klass, "to_a", "to_ary");
|
||||
|
||||
DEFINE_CVHUMOMENTS_GETTER(hu1);
|
||||
DEFINE_CVHUMOMENTS_GETTER(hu2);
|
||||
DEFINE_CVHUMOMENTS_GETTER(hu3);
|
||||
DEFINE_CVHUMOMENTS_GETTER(hu4);
|
||||
DEFINE_CVHUMOMENTS_GETTER(hu5);
|
||||
DEFINE_CVHUMOMENTS_GETTER(hu6);
|
||||
DEFINE_CVHUMOMENTS_GETTER(hu7);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_allocate(VALUE klass)
|
||||
{
|
||||
CvHuMoments *ptr;
|
||||
return Data_Make_Struct(klass, CvHuMoments, 0, -1, ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* CvHuMoments.new(<i>src_moments</i>)
|
||||
*
|
||||
* Calculates the seven Hu invariants.
|
||||
* <i>src_moments</i> The input moments
|
||||
*
|
||||
* seven Hu invariants that are defined as:
|
||||
* h1=η20+η02
|
||||
* h2=(η20-η02)²+4η11²
|
||||
* h3=(η30-3η12)²+ (3η21-η03)²
|
||||
* h4=(η30+η12)²+ (η21+η03)²
|
||||
* h5=(η30-3η12)(η30+η12)[(η30+η12)²-3(η21+η03)²]+(3η21-η03)(η21+η03)[3(η30+η12)²-(η21+η03)²]
|
||||
* h6=(η20-η02)[(η30+η12)²- (η21+η03)²]+4η11(η30+η12)(η21+η03)
|
||||
* h7=(3η21-η03)(η21+η03)[3(η30+η12)²-(η21+η03)²]-(η30-3η12)(η21+η03)[3(η30+η12)²-(η21+η03)²]
|
||||
* where ηi,j are normalized central moments of 2-nd and 3-rd orders. The computed values are proved to be invariant to the image scaling, rotation, and reflection except the seventh one, whose sign is changed by reflection.
|
||||
*/
|
||||
VALUE
|
||||
rb_initialize(VALUE self, VALUE src_moments)
|
||||
{
|
||||
if (rb_obj_is_kind_of(src_moments, cCvMoments::rb_class()))
|
||||
cvGetHuMoments(CVMOMENTS(src_moments), CVHUMOMENTS(self));
|
||||
else
|
||||
rb_raise(rb_eTypeError, "argument 1 (src_moments) should be %s.",
|
||||
rb_class2name(cCvMoments::rb_class()));
|
||||
return self;
|
||||
}
|
||||
|
||||
CVHUMOMENTS_GETTER(hu1);
|
||||
CVHUMOMENTS_GETTER(hu2);
|
||||
CVHUMOMENTS_GETTER(hu3);
|
||||
CVHUMOMENTS_GETTER(hu4);
|
||||
CVHUMOMENTS_GETTER(hu5);
|
||||
CVHUMOMENTS_GETTER(hu6);
|
||||
CVHUMOMENTS_GETTER(hu7);
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* to_ary -> [hu1, hu2, ... ,hu7]
|
||||
*
|
||||
* Return values by Array.
|
||||
*/
|
||||
VALUE
|
||||
rb_to_ary(VALUE self)
|
||||
{
|
||||
CvHuMoments *hu_moments = CVHUMOMENTS(self);
|
||||
return rb_ary_new3(7,
|
||||
rb_float_new(hu_moments->hu1),
|
||||
rb_float_new(hu_moments->hu2),
|
||||
rb_float_new(hu_moments->hu3),
|
||||
rb_float_new(hu_moments->hu4),
|
||||
rb_float_new(hu_moments->hu5),
|
||||
rb_float_new(hu_moments->hu6),
|
||||
rb_float_new(hu_moments->hu7));
|
||||
}
|
||||
|
||||
VALUE
|
||||
new_object(CvMoments *src_moments)
|
||||
{
|
||||
VALUE object = rb_allocate(rb_class());
|
||||
cvGetHuMoments(src_moments, CVHUMOMENTS(object));
|
||||
return object;
|
||||
}
|
||||
|
||||
__NAMESPACE_END_CVHUMOMENTS
|
||||
__NAMESPACE_END_OPENCV
|
51
ext/cvhumoments.h
Normal file
51
ext/cvhumoments.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/************************************************************
|
||||
|
||||
cvhumoments.h -
|
||||
|
||||
$Author: ser1zw $
|
||||
|
||||
Copyright (C) 2011 ser1zw
|
||||
|
||||
************************************************************/
|
||||
#ifndef RUBY_OPENCV_CVHUMOMENTS_H
|
||||
#define RUBY_OPENCV_CVHUMOMENTS_H
|
||||
|
||||
#include "opencv.h"
|
||||
|
||||
#define __NAMESPACE_BEGIN_CVHUMOMENTS namespace cCvHuMoments{
|
||||
#define __NAMESPACE_END_CVHUMOMENTS }
|
||||
|
||||
__NAMESPACE_BEGIN_OPENCV
|
||||
__NAMESPACE_BEGIN_CVHUMOMENTS
|
||||
|
||||
VALUE rb_class();
|
||||
|
||||
void define_ruby_class();
|
||||
|
||||
VALUE rb_allocate(VALUE klass);
|
||||
VALUE rb_initialize(VALUE src_moments, VALUE self);
|
||||
|
||||
VALUE rb_hu1(VALUE self);
|
||||
VALUE rb_hu2(VALUE self);
|
||||
VALUE rb_hu3(VALUE self);
|
||||
VALUE rb_hu4(VALUE self);
|
||||
VALUE rb_hu5(VALUE self);
|
||||
VALUE rb_hu6(VALUE self);
|
||||
VALUE rb_hu7(VALUE self);
|
||||
VALUE rb_to_ary(VALUE self);
|
||||
|
||||
VALUE new_object(CvMoments *cvmoments);
|
||||
|
||||
__NAMESPACE_END_CVHUMOMENTS
|
||||
|
||||
inline CvHuMoments*
|
||||
CVHUMOMENTS(VALUE object)
|
||||
{
|
||||
CvHuMoments *ptr;
|
||||
Data_Get_Struct(object, CvHuMoments, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
__NAMESPACE_END_OPENCV
|
||||
|
||||
#endif // RUBY_OPENCV_CVHUMOMENTS_H
|
|
@ -542,6 +542,7 @@ extern "C"{
|
|||
mOpenCV::cCvFont::define_ruby_class();
|
||||
mOpenCV::cIplConvKernel::define_ruby_class();
|
||||
mOpenCV::cCvMoments::define_ruby_class();
|
||||
mOpenCV::cCvHuMoments::define_ruby_class();
|
||||
mOpenCV::cCvConvexityDefect::define_ruby_class();
|
||||
|
||||
mOpenCV::cCvMemStorage::define_ruby_class();
|
||||
|
|
|
@ -94,6 +94,7 @@ extern "C"{
|
|||
#include "cvfont.h"
|
||||
#include "iplconvkernel.h"
|
||||
#include "cvmoments.h"
|
||||
#include "cvhumoments.h"
|
||||
#include "cvconvexitydefect.h"
|
||||
#include "cvpoint3d32f.h"
|
||||
|
||||
|
|
83
test/test_cvhumoments.rb
Executable file
83
test/test_cvhumoments.rb
Executable file
|
@ -0,0 +1,83 @@
|
|||
#!/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::CvHuMoment
|
||||
class TestCvHuMoments < OpenCVTestCase
|
||||
def setup
|
||||
@mat = create_cvmat(128, 128, :cv8u, 1) { |j, i|
|
||||
if j >= 32 and j < 96 and i >= 16 and i < 112
|
||||
CvScalar.new(0)
|
||||
elsif j >= 16 and j < 112 and i >= 16 and i < 112
|
||||
CvScalar.new(128)
|
||||
else
|
||||
CvScalar.new(255)
|
||||
end
|
||||
}
|
||||
@moment1 = CvMoments.new
|
||||
@moment2 = CvMoments.new(nil, true)
|
||||
@moment3 = CvMoments.new(@mat)
|
||||
@moment4 = CvMoments.new(@mat, true)
|
||||
|
||||
@hu_moments1 = CvHuMoments.new(@moment1)
|
||||
@hu_moments2 = CvHuMoments.new(@moment2)
|
||||
@hu_moments3 = CvHuMoments.new(@moment3)
|
||||
@hu_moments4 = CvHuMoments.new(@moment4)
|
||||
end
|
||||
|
||||
def test_initialize
|
||||
[@hu_moments1, @hu_moments2, @hu_moments3, @hu_moments4].each { |m|
|
||||
assert_not_nil(m)
|
||||
assert_equal(CvHuMoments, m.class)
|
||||
}
|
||||
|
||||
assert_raise(TypeError) {
|
||||
CvHuMoments.new('foo')
|
||||
}
|
||||
end
|
||||
|
||||
def test_huX
|
||||
hu_moments = [@hu_moments1.hu1, @hu_moments1.hu2, @hu_moments1.hu3, @hu_moments1.hu4,
|
||||
@hu_moments1.hu5, @hu_moments1.hu6, @hu_moments1.hu7]
|
||||
hu_moments.each { |hu|
|
||||
assert_in_delta(0.0, hu, 0.000001)
|
||||
}
|
||||
|
||||
hu_moments = [@hu_moments2.hu1, @hu_moments2.hu2, @hu_moments2.hu3, @hu_moments2.hu4,
|
||||
@hu_moments2.hu5, @hu_moments2.hu6, @hu_moments2.hu7]
|
||||
hu_moments.each { |hu|
|
||||
assert_in_delta(0.0, hu, 0.000001)
|
||||
}
|
||||
|
||||
hu_moments = [@hu_moments3.hu2, @hu_moments3.hu3, @hu_moments3.hu4,
|
||||
@hu_moments3.hu5, @hu_moments3.hu6, @hu_moments3.hu7]
|
||||
assert_in_delta(0.001771, @hu_moments3.hu1, 0.000001)
|
||||
hu_moments.each { |hu|
|
||||
assert_in_delta(0.0, hu, 0.000001)
|
||||
}
|
||||
|
||||
hu_moments = [@hu_moments4.hu3, @hu_moments4.hu4,
|
||||
@hu_moments4.hu5, @hu_moments4.hu6, @hu_moments4.hu7]
|
||||
assert_in_delta(0.361650, @hu_moments4.hu1, 0.000001)
|
||||
assert_in_delta(0.000625, @hu_moments4.hu2, 0.000001)
|
||||
hu_moments.each { |hu|
|
||||
assert_in_delta(0.0, hu, 0.000001)
|
||||
}
|
||||
end
|
||||
|
||||
def test_to_ary
|
||||
[@hu_moments4.to_ary, @hu_moments4.to_a].each { |hu_moments|
|
||||
assert_equal(7, hu_moments.size)
|
||||
assert_in_delta(0.361650, hu_moments[0], 0.000001)
|
||||
assert_in_delta(0.000625, hu_moments[1], 0.000001)
|
||||
hu_moments[2..7].each { |hu|
|
||||
assert_in_delta(0.0, hu, 0.000001)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue