1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

implemented rb_cvAlloc and replaced cvAlloc with rb_cvAlloc to allocate memory buffer as much as possible

This commit is contained in:
ser1zw 2011-04-28 00:11:46 +09:00
parent 196c567ee0
commit 586f2161eb
6 changed files with 94 additions and 29 deletions

View file

@ -921,7 +921,7 @@ rb_square_q(VALUE self)
VALUE VALUE
rb_to_CvMat(VALUE self) rb_to_CvMat(VALUE self)
{ {
return DEPEND_OBJECT(rb_klass, cvGetMat(CVARR(self), CVALLOC(CvMat)), self); return DEPEND_OBJECT(rb_klass, cvGetMat(CVARR(self), RB_CVALLOC(CvMat)), self);
} }
/* /*
@ -965,7 +965,7 @@ rb_sub_rect(VALUE self, VALUE args)
rb_raise(rb_eArgError, "wrong number of arguments (%ld of 1 or 2 or 4)", RARRAY_LEN(args)); rb_raise(rb_eArgError, "wrong number of arguments (%ld of 1 or 2 or 4)", RARRAY_LEN(args));
} }
return DEPEND_OBJECT(rb_klass, return DEPEND_OBJECT(rb_klass,
cvGetSubRect(CVARR(self), CVALLOC(CvMat), area), cvGetSubRect(CVARR(self), RB_CVALLOC(CvMat), area),
self); self);
} }
@ -994,7 +994,7 @@ rb_slice_width(VALUE self, VALUE num)
VALUE ary = rb_ary_new2(n); VALUE ary = rb_ary_new2(n);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
CvRect rect = {div_x * i, 0, div_x, size.height}; CvRect rect = {div_x * i, 0, div_x, size.height};
rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), CVALLOC(CvMat), rect), self)); rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), RB_CVALLOC(CvMat), rect), self));
} }
return ary; return ary;
} }
@ -1019,7 +1019,7 @@ rb_slice_height(VALUE self, VALUE num)
VALUE ary = rb_ary_new2(n); VALUE ary = rb_ary_new2(n);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
CvRect rect = {0, div_y * i, size.width, div_y}; CvRect rect = {0, div_y * i, size.width, div_y};
rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), CVALLOC(CvMat), rect), self)); rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), RB_CVALLOC(CvMat), rect), self));
} }
return ary; return ary;
} }
@ -1041,10 +1041,11 @@ rb_row(VALUE self, VALUE args)
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
VALUE value = rb_ary_entry(args, i); VALUE value = rb_ary_entry(args, i);
if (FIXNUM_P(value)) { if (FIXNUM_P(value)) {
rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), CVALLOC(CvMat), FIX2INT(value)), self)); rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), RB_CVALLOC(CvMat), FIX2INT(value)), self));
}else{ }else{
CvSlice slice = VALUE_TO_CVSLICE(value); CvSlice slice = VALUE_TO_CVSLICE(value);
rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRows(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self)); rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRows(CVARR(self), RB_CVALLOC(CvMat),
slice.start_index, slice.end_index), self));
} }
} }
return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0); return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0);
@ -1067,10 +1068,11 @@ rb_col(VALUE self, VALUE args)
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
VALUE value = rb_ary_entry(args, i); VALUE value = rb_ary_entry(args, i);
if (FIXNUM_P(value)) { if (FIXNUM_P(value)) {
rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), CVALLOC(CvMat), FIX2INT(value)), self)); rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), RB_CVALLOC(CvMat), FIX2INT(value)), self));
}else{ }else{
CvSlice slice = VALUE_TO_CVSLICE(value); CvSlice slice = VALUE_TO_CVSLICE(value);
rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCols(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self)); rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCols(CVARR(self), RB_CVALLOC(CvMat),
slice.start_index, slice.end_index), self));
} }
} }
return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0); return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0);
@ -1089,7 +1091,7 @@ rb_each_row(VALUE self)
{ {
int rows = CVMAT(self)->rows; int rows = CVMAT(self)->rows;
for (int i = 0; i < rows; i++) { for (int i = 0; i < rows; i++) {
rb_yield(DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), CVALLOC(CvMat), i), self)); rb_yield(DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), RB_CVALLOC(CvMat), i), self));
} }
return self; return self;
} }
@ -1107,7 +1109,7 @@ rb_each_col(VALUE self)
{ {
int cols = CVMAT(self)->cols; int cols = CVMAT(self)->cols;
for (int i = 0; i < cols; i++) { for (int i = 0; i < cols; i++) {
rb_yield(DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), CVALLOC(CvMat), i), self)); rb_yield(DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), RB_CVALLOC(CvMat), i), self));
} }
return self; return self;
} }
@ -1127,7 +1129,7 @@ rb_diag(int argc, VALUE *argv, VALUE self)
if (rb_scan_args(argc, argv, "01", &val) < 1) { if (rb_scan_args(argc, argv, "01", &val) < 1) {
val = INT2FIX(0); val = INT2FIX(0);
} }
return DEPEND_OBJECT(rb_klass, cvGetDiag(CVARR(self), CVALLOC(CvMat), NUM2INT(val)), self); return DEPEND_OBJECT(rb_klass, cvGetDiag(CVARR(self), RB_CVALLOC(CvMat), NUM2INT(val)), self);
} }
/* /*
@ -1410,7 +1412,8 @@ rb_reshape(VALUE self, VALUE hash)
rb_raise(rb_eTypeError, "argument should be Hash that contaion key (:row, :channel)."); rb_raise(rb_eTypeError, "argument should be Hash that contaion key (:row, :channel).");
VALUE channel = rb_hash_aref(hash, ID2SYM(rb_intern("channel"))); VALUE channel = rb_hash_aref(hash, ID2SYM(rb_intern("channel")));
VALUE rows = rb_hash_aref(hash, ID2SYM(rb_intern("rows"))); VALUE rows = rb_hash_aref(hash, ID2SYM(rb_intern("rows")));
return DEPEND_OBJECT(rb_klass, cvReshape(CVARR(self), CVALLOC(CvMat), NIL_P(channel) ? 0 : FIX2INT(channel), NIL_P(rows) ? 0 : FIX2INT(rows)), self); return DEPEND_OBJECT(rb_klass, cvReshape(CVARR(self), RB_CVALLOC(CvMat), NIL_P(channel) ? 0 : FIX2INT(channel),
NIL_P(rows) ? 0 : FIX2INT(rows)), self);
} }
/* /*
@ -3212,7 +3215,7 @@ rb_good_features_to_track(int argc, VALUE *argv, VALUE self)
int np = GF_MAX(good_features_to_track_option); int np = GF_MAX(good_features_to_track_option);
if(!(np > 0)) if(!(np > 0))
rb_raise(rb_eArgError, "option :max should be positive value."); rb_raise(rb_eArgError, "option :max should be positive value.");
CvPoint2D32f *p32 = (CvPoint2D32f*)cvAlloc(sizeof(CvPoint2D32f) * np); CvPoint2D32f *p32 = (CvPoint2D32f*)rb_cvAlloc(sizeof(CvPoint2D32f) * np);
if(!p32) if(!p32)
rb_raise(rb_eNoMemError, "failed to allocate memory."); rb_raise(rb_eNoMemError, "failed to allocate memory.");
cvGoodFeaturesToTrack(src, &eigen, &tmp, p32, &np, NUM2DBL(quality_level), NUM2DBL(min_distance), cvGoodFeaturesToTrack(src, &eigen, &tmp, p32, &np, NUM2DBL(quality_level), NUM2DBL(min_distance),

View file

@ -333,7 +333,7 @@ rb_seq_push(VALUE self, VALUE args, int flag)
cvSeqPush(seq, DATA_PTR(object)); cvSeqPush(seq, DATA_PTR(object));
} }
else if (rb_obj_is_kind_of(object, rb_klass) && CLASS_OF(rb_first(object)) == klass) { // object is CvSeq else if (rb_obj_is_kind_of(object, rb_klass) && CLASS_OF(rb_first(object)) == klass) { // object is CvSeq
buffer = cvCvtSeqToArray(CVSEQ(object), cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); buffer = cvCvtSeqToArray(CVSEQ(object), rb_cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size));
cvSeqPushMulti(seq, buffer, CVSEQ(object)->total, flag); cvSeqPushMulti(seq, buffer, CVSEQ(object)->total, flag);
cvFree(&buffer); cvFree(&buffer);
} }

View file

@ -90,7 +90,7 @@ rb_initialize(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "22", &width, &height, &depth, &channel); rb_scan_args(argc, argv, "22", &width, &height, &depth, &channel);
int _depth = argc < 3 ? CV_8U : FIX2INT(depth); int _depth = argc < 3 ? CV_8U : FIX2INT(depth);
int _channel = argc < 4 ? 3 : FIX2INT(channel); int _channel = argc < 4 ? 3 : FIX2INT(channel);
DATA_PTR(self) = cvCreateImage(cvSize(FIX2INT(width), FIX2INT(height)), cvIplDepth(_depth), _channel); DATA_PTR(self) = rb_cvCreateImage(cvSize(FIX2INT(width), FIX2INT(height)), cvIplDepth(_depth), _channel);
return self; return self;
} }
@ -267,7 +267,7 @@ rb_smoothness(int argc, VALUE *argv, VALUE self)
p64DepthImage = NULL; p64DepthImage = NULL;
pFourierImage = create_fourier_image(IPLIMAGE(self)); pFourierImage = create_fourier_image(IPLIMAGE(self));
} else { } else {
p64DepthImage = cvCreateImage(cvGetSize(IPLIMAGE(self)), IPL_DEPTH_64F, 1); p64DepthImage = rb_cvCreateImage(cvGetSize(IPLIMAGE(self)), IPL_DEPTH_64F, 1);
cvConvertScale(CVARR(self), p64DepthImage, 1.0, 0.0); cvConvertScale(CVARR(self), p64DepthImage, 1.0, 0.0);
pFourierImage = create_fourier_image(p64DepthImage); pFourierImage = create_fourier_image(p64DepthImage);
} }
@ -414,9 +414,9 @@ create_fourier_image(const IplImage *im)
IplImage *image_Re; IplImage *image_Re;
IplImage *image_Im; IplImage *image_Im;
realInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1); realInput = rb_cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1);
imaginaryInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1); imaginaryInput = rb_cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1);
complexInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 2); complexInput = rb_cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 2);
cvScale(im, realInput, 1.0, 0.0); cvScale(im, realInput, 1.0, 0.0);
cvZero(imaginaryInput); cvZero(imaginaryInput);
@ -426,8 +426,8 @@ create_fourier_image(const IplImage *im)
dft_N = cvGetOptimalDFTSize( im->width - 1 ); dft_N = cvGetOptimalDFTSize( im->width - 1 );
dft_A = rb_cvCreateMat( dft_M, dft_N, CV_64FC2 ); dft_A = rb_cvCreateMat( dft_M, dft_N, CV_64FC2 );
image_Re = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1); image_Re = rb_cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
image_Im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1); image_Im = rb_cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
// copy A to dft_A and pad dft_A with zeros // copy A to dft_A and pad dft_A with zeros
cvGetSubRect( dft_A, &tmp, cvRect(0,0, im->width, im->height)); cvGetSubRect( dft_A, &tmp, cvRect(0,0, im->width, im->height));
@ -484,8 +484,8 @@ create_frequency_filtered_image(const IplImage *pImage, int low, int high)
box.size.width = high; box.size.width = high;
box.size.height = high; box.size.height = high;
IplImage *pFilterMask = cvCreateImage( cvGetSize(pImage), IPL_DEPTH_64F, 1 ); IplImage *pFilterMask = rb_cvCreateImage( cvGetSize(pImage), IPL_DEPTH_64F, 1 );
IplImage *pFiltered = cvCreateImage( cvGetSize(pImage), IPL_DEPTH_64F, 1 ); IplImage *pFiltered = rb_cvCreateImage( cvGetSize(pImage), IPL_DEPTH_64F, 1 );
cvZero(pFilterMask); cvZero(pFilterMask);
cvZero(pFiltered); cvZero(pFiltered);
@ -525,13 +525,13 @@ high_pass_range(const IplImage *pImage, float lostPercentage, int &outLow, int &
VALUE VALUE
new_object(int width, int height, int type) new_object(int width, int height, int type)
{ {
return OPENCV_OBJECT(rb_klass, cvCreateImage(cvSize(width, height), cvIplDepth(type), CV_MAT_CN(type))); return OPENCV_OBJECT(rb_klass, rb_cvCreateImage(cvSize(width, height), cvIplDepth(type), CV_MAT_CN(type)));
} }
VALUE VALUE
new_object(CvSize size, int type) new_object(CvSize size, int type)
{ {
return OPENCV_OBJECT(rb_klass, cvCreateImage(size, cvIplDepth(type), CV_MAT_CN(type))); return OPENCV_OBJECT(rb_klass, rb_cvCreateImage(size, cvIplDepth(type), CV_MAT_CN(type)));
} }
__NAMESPACE_END_IPLIMAGE __NAMESPACE_END_IPLIMAGE

View file

@ -129,6 +129,35 @@ release_iplconvkernel_object(void *ptr)
} }
} }
/*
* Allocates a memory buffer
* When memory allocation is failed, run GC and retry it
*/
void*
rb_cvAlloc(size_t size)
{
void* ptr = NULL;
try {
ptr = cvAlloc(size);
}
catch(cv::Exception& e) {
if (e.code != CV_StsNoMem)
rb_raise(rb_eRuntimeError, "%s", e.what());
rb_gc_start();
try {
ptr = cvAlloc(size);
}
catch (cv::Exception& e) {
if (e.code == CV_StsNoMem)
rb_raise(rb_eNoMemError, "%s", e.what());
else
rb_raise(rb_eRuntimeError, "%s", e.what());
}
}
return ptr;
}
/* /*
* Creates CvMat and underlying data * Creates CvMat and underlying data
* When memory allocation is failed, run GC and retry it * When memory allocation is failed, run GC and retry it
@ -158,6 +187,35 @@ rb_cvCreateMat(int height, int width, int type)
return ptr; return ptr;
} }
/*
* Create IplImage header and allocate underlying data
* When memory allocation is failed, run GC and retry it
*/
IplImage*
rb_cvCreateImage(CvSize size, int depth, int channels)
{
IplImage* ptr = NULL;
try {
ptr = cvCreateImage(size, depth, channels);
}
catch(cv::Exception& e) {
if (e.code != CV_StsNoMem)
rb_raise(rb_eRuntimeError, "%s", e.what());
rb_gc_start();
try {
ptr = cvCreateImage(size, depth, channels);
}
catch (cv::Exception& e) {
if (e.code == CV_StsNoMem)
rb_raise(rb_eNoMemError, "%s", e.what());
else
rb_raise(rb_eRuntimeError, "%s", e.what());
}
}
return ptr;
}
VALUE rb_module; VALUE rb_module;
VALUE rb_opencv_constants; VALUE rb_opencv_constants;

View file

@ -135,7 +135,7 @@ extern "C"{
#include "mouseevent.h" #include "mouseevent.h"
// memory management wrapper // memory management wrapper
#define CVALLOC(type) (type*)cvAlloc(sizeof(type)) #define RB_CVALLOC(type) (type*)rb_cvAlloc(sizeof(type))
// useful macros // useful macros
#define IF_INT(val, ifnone) NIL_P(val) ? ifnone : NUM2INT(val) #define IF_INT(val, ifnone) NIL_P(val) ? ifnone : NUM2INT(val)
@ -185,7 +185,9 @@ void release_iplconvkernel_object(void *ptr);
VALUE rb_module_opencv(); VALUE rb_module_opencv();
void define_ruby_module(); void define_ruby_module();
void* rb_cvAlloc(size_t size);
CvMat* rb_cvCreateMat(int height, int width, int type); CvMat* rb_cvCreateMat(int height, int width, int type);
IplImage* rb_cvCreateImage(CvSize size, int depth, int channels);
// Ruby/OpenCV inline functions // Ruby/OpenCV inline functions
inline CvArr* inline CvArr*

View file

@ -181,16 +181,18 @@ CVPOINTS_FROM_POINT_SET(VALUE object, CvPoint **pointset)
CvPoint2D32f p32; CvPoint2D32f p32;
if(rb_obj_is_kind_of(object, cCvSeq::rb_class())){ if(rb_obj_is_kind_of(object, cCvSeq::rb_class())){
if(CV_IS_SEQ_POINT_SET(CVSEQ(object))){ if(CV_IS_SEQ_POINT_SET(CVSEQ(object))){
*pointset = (CvPoint*)cvCvtSeqToArray(CVSEQ(object), cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); *pointset = (CvPoint*)cvCvtSeqToArray(CVSEQ(object),
rb_cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size));
return CVSEQ(object)->total; return CVSEQ(object)->total;
}else{ }else{
rb_raise(rb_eTypeError, "sequence is not contain %s or %s.", rb_class2name(cCvPoint::rb_class()), rb_class2name(cCvPoint2D32f::rb_class())); rb_raise(rb_eTypeError, "sequence is not contain %s or %s.",
rb_class2name(cCvPoint::rb_class()), rb_class2name(cCvPoint2D32f::rb_class()));
} }
}else if(rb_obj_is_kind_of(object, cCvMat::rb_class())){ }else if(rb_obj_is_kind_of(object, cCvMat::rb_class())){
/* to do */ /* to do */
rb_raise(rb_eNotImpError, "CvMat to CvSeq conversion not implemented."); rb_raise(rb_eNotImpError, "CvMat to CvSeq conversion not implemented.");
}else if(rb_obj_is_kind_of(object, rb_cArray)){ }else if(rb_obj_is_kind_of(object, rb_cArray)){
*pointset = (CvPoint*)cvAlloc(RARRAY_LEN(object) * sizeof(CvPoint)); *pointset = (CvPoint*)rb_cvAlloc(RARRAY_LEN(object) * sizeof(CvPoint));
for(int i = 0; i < RARRAY_LEN(object); i++){ for(int i = 0; i < RARRAY_LEN(object); i++){
(*pointset)[i].x = NUM2INT(rb_funcall(rb_ary_entry(object, i), rb_intern("x"), 0)); (*pointset)[i].x = NUM2INT(rb_funcall(rb_ary_entry(object, i), rb_intern("x"), 0));
(*pointset)[i].y = NUM2INT(rb_funcall(rb_ary_entry(object, i), rb_intern("y"), 0)); (*pointset)[i].y = NUM2INT(rb_funcall(rb_ary_entry(object, i), rb_intern("y"), 0));