Arquivos
php-opencv/source/opencv2/core/opencv_mat.cc
T
2019-03-25 00:47:28 +02:00

870 linhas
27 KiB
C++

/*
+----------------------------------------------------------------------+
| PHP-OpenCV |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| hihozhou@gmail.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: HaiHao Zhou <hihozhou@gmail.com> |
+----------------------------------------------------------------------+
*/
#include "../../../php_opencv.h"
#include "opencv_mat.h"
#include "opencv_type.h"
#include "../../../opencv_exception.h"
zend_object_handlers opencv_mat_object_handlers;
zend_class_entry *opencv_mat_ce;
/**
* @param type
* @return
*/
zend_object* opencv_mat_create_handler(zend_class_entry *type)
{
int size = sizeof(opencv_mat_object)+zend_object_properties_size(type);
opencv_mat_object *obj = (opencv_mat_object *)ecalloc(1,size);
memset(obj, 0, size);
zend_object_std_init(&obj->std, type);
object_properties_init(&obj->std, type);
obj->std.ce = type;
obj->std.handlers = &opencv_mat_object_handlers;
return &obj->std;
}
void opencv_mat_free_obj(zend_object *object)
{
opencv_mat_object *obj;
obj = get_mat_obj(object);
delete obj->mat;
zend_object_std_dtor(object);
}
void opencv_mat_update_property_by_c_mat(zval *z,Mat *mat){
zend_update_property_long(opencv_mat_ce, z, "rows", sizeof("rows")-1, mat->rows);
zend_update_property_long(opencv_mat_ce, z, "cols", sizeof("cols")-1, mat->cols);
zend_update_property_long(opencv_mat_ce, z, "dims", sizeof("dims")-1, mat->dims);
zend_update_property_long(opencv_mat_ce, z, "type", sizeof("type")-1, mat->type());
//zend_update_property_long(opencv_mat_ce, z, "depth", sizeof("depth")-1, mat->depth());
if (mat->dims > 2) {
zval shape_zval;
array_init(&shape_zval);
for(int i = 0; i < mat->dims; i++)
{
add_next_index_long(&shape_zval, mat->size.p[i]);
}
zend_update_property(opencv_mat_ce, z, "shape", sizeof("shape")-1, &shape_zval);
}
}
void opencv_mat_at(Mat *mat, int *idx, long channel, zval *value_zval, long *return_long_val, double *return_double_val) {
uchar *return_uchar_val;
schar *return_schar_val;
ushort *return_ushort_val;
short *return_short_val;
int *return_int_val;
float *return_float_val;
switch(mat->type()) {
//CV_8U
case CV_8UC1: return_uchar_val = &mat->at<uchar>(idx); break;
case CV_8UC2: return_uchar_val = &mat->at<Vec2b>(idx)[channel]; break;
case CV_8UC3: return_uchar_val = &mat->at<Vec3b>(idx)[channel]; break;
case CV_8UC4: return_uchar_val = &mat->at<Vec4b>(idx)[channel]; break;
//CV_8S
case CV_8SC1: return_schar_val = &mat->at<schar>(idx); break;
case CV_8SC2: return_schar_val = &mat->at<Vec<schar, 2>>(idx)[channel]; break;
case CV_8SC3: return_schar_val = &mat->at<Vec<schar, 3>>(idx)[channel]; break;
case CV_8SC4: return_schar_val = &mat->at<Vec<schar, 4>>(idx)[channel]; break;
//CV_16U
case CV_16UC1: return_ushort_val = &mat->at<ushort>(idx); break;
case CV_16UC2: return_ushort_val = &mat->at<Vec2w>(idx)[channel]; break;
case CV_16UC3: return_ushort_val = &mat->at<Vec3w>(idx)[channel]; break;
case CV_16UC4: return_ushort_val = &mat->at<Vec4w>(idx)[channel]; break;
//CV_16S
case CV_16SC1: return_short_val = &mat->at<short>(idx); break;
case CV_16SC2: return_short_val = &mat->at<Vec2s>(idx)[channel]; break;
case CV_16SC3: return_short_val = &mat->at<Vec3s>(idx)[channel]; break;
case CV_16SC4: return_short_val = &mat->at<Vec4s>(idx)[channel]; break;
//CV_32S
case CV_32SC1: return_int_val = &mat->at<int>(idx); break;
case CV_32SC2: return_int_val = &mat->at<Vec2i>(idx)[channel]; break;
case CV_32SC3: return_int_val = &mat->at<Vec3i>(idx)[channel]; break;
case CV_32SC4: return_int_val = &mat->at<Vec4i>(idx)[channel]; break;
//CV_32F
case CV_32FC1: return_float_val = &mat->at<float>(idx); break;
case CV_32FC2: return_float_val = &mat->at<Vec2f>(idx)[channel]; break;
case CV_32FC3: return_float_val = &mat->at<Vec3f>(idx)[channel]; break;
case CV_32FC4: return_float_val = &mat->at<Vec4f>(idx)[channel]; break;
//CV_64F
case CV_64FC1: return_double_val = &mat->at<double>(idx); break;
case CV_64FC2: return_double_val = &mat->at<Vec2d>(idx)[channel]; break;
case CV_64FC3: return_double_val = &mat->at<Vec3d>(idx)[channel]; break;
case CV_64FC4: return_double_val = &mat->at<Vec4d>(idx)[channel]; break;
default: opencv_throw_exception("Wrong Mat type"); break;
}
//get px value
switch(mat->depth()){
case CV_8U: *return_long_val = *return_uchar_val; break;
case CV_8S: *return_long_val = *return_schar_val; break;
case CV_16U: *return_long_val = *return_ushort_val; break;
case CV_16S: *return_long_val = *return_short_val; break;
case CV_32S: *return_long_val = *return_int_val; break;
case CV_32F: *return_double_val = *return_float_val; break;
case CV_64F: break;
default: opencv_throw_exception("Wrong Mat type"); break;
}
//set px value
if (value_zval != NULL) {
switch(mat->depth()){
case CV_32F:
case CV_64F: convert_to_double(value_zval); break;
default: convert_to_long(value_zval); break;
}
zend_long value = Z_LVAL_P(value_zval);
switch(mat->depth()){
case CV_8U: *return_uchar_val = saturate_cast<uchar>(Z_LVAL_P(value_zval)); break;
case CV_8S: *return_schar_val = saturate_cast<schar>(Z_LVAL_P(value_zval)); break;
case CV_16U: *return_ushort_val = saturate_cast<ushort>(Z_LVAL_P(value_zval)); break;
case CV_16S: *return_short_val = saturate_cast<short>(Z_LVAL_P(value_zval)); break;
case CV_32S: *return_int_val = saturate_cast<int>(Z_LVAL_P(value_zval)); break;
case CV_32F: *return_float_val = saturate_cast<float>(Z_DVAL_P(value_zval)); break;
case CV_64F: *return_double_val = saturate_cast<double>(Z_DVAL_P(value_zval)); break;
default: opencv_throw_exception("Wrong Mat type"); break;
}
}
}
/**
* Mat __construct
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, __construct)
{
long rows, cols, type;
zval *scalar_zval = NULL;
Scalar scalar;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll|O", &rows, &cols, &type, &scalar_zval,opencv_scalar_ce) == FAILURE) {
RETURN_NULL();
}
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
if(scalar_zval != NULL){
opencv_scalar_object *scalar_object = Z_PHP_SCALAR_OBJ_P(scalar_zval);
scalar = *(scalar_object->scalar);
}else{
scalar=Scalar(0);
}
Mat M((int)rows, (int)cols, (int)type);
// obj->mat = new Mat(M);
obj->mat = new Mat((int)rows, (int)cols, (int)type, scalar);
//obj->mat = new Mat((int)rows, (int)cols, (int)type); //TODO Why Mat array not correct
opencv_mat_update_property_by_c_mat(getThis(), obj->mat);
}
/**
* print Mat data
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, print)
{
long type = Formatter::FMT_DEFAULT;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &type) == FAILURE) {
RETURN_NULL();
}
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
//long转cv::Formatter::FormatType类型
cv::Formatter::FormatType formatType = static_cast<cv::Formatter::FormatType>((int)type);
std::cout << format(*(obj->mat), formatType) << std::endl;
RETURN_NULL();
}
PHP_METHOD(opencv_mat, type)
{
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
RETURN_LONG(obj->mat->type());
}
PHP_METHOD(opencv_mat, depth)
{
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
RETURN_LONG(obj->mat->depth());
}
PHP_METHOD(opencv_mat, channels)
{
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
RETURN_LONG(obj->mat->channels());
}
PHP_METHOD(opencv_mat, total)
{
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
RETURN_LONG(obj->mat->total());
}
PHP_METHOD(opencv_mat, empty)
{
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
RETURN_LONG(obj->mat->empty());
}
PHP_METHOD(opencv_mat, ones)
{
long rows, cols, flags;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &rows, &cols, &flags) == FAILURE) {
RETURN_NULL();
}
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(&instance);
Mat im = Mat::ones((int)rows, (int)cols, (int)flags);
obj->mat=new Mat(im);
//update php Mat object property
opencv_mat_update_property_by_c_mat(&instance, obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
PHP_METHOD(opencv_mat, zeros)
{
long rows, cols, flags;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &rows, &cols, &flags) == FAILURE) {
RETURN_NULL();
}
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(&instance);
Mat im = Mat::zeros((int)rows, (int)cols, (int)flags);
obj->mat=new Mat(im);
//update php Mat object property
opencv_mat_update_property_by_c_mat(&instance, obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
PHP_METHOD(opencv_mat, zeros_by_size)
{
zval *size_zval;
long flags;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &size_zval, opencv_size_ce, &flags) == FAILURE) {
RETURN_NULL();
}
opencv_size_object *size_object = Z_PHP_SIZE_OBJ_P(size_zval);
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(&instance);
Mat im = Mat::zeros(*size_object->size, (int)flags);
obj->mat=new Mat(im);
opencv_mat_update_property_by_c_mat(&instance, obj->mat);
RETURN_ZVAL(&instance,0,0);
}
/**
* Mat->clone()
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, clone)
{
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *new_obj = Z_PHP_MAT_OBJ_P(&instance);
opencv_mat_object *old_obj = Z_PHP_MAT_OBJ_P(getThis());
Mat new_mat = old_obj->mat->clone();
new_obj->mat = new Mat(new_mat);
//update php Mat object property
opencv_mat_update_property_by_c_mat(&instance, new_obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
/**
* Mat->isContinuous
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, is_continuous)
{
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
bool isContinuous = obj->mat->isContinuous();
RETURN_BOOL(isContinuous);
}
/**
* Mat->isSubmatrix
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, is_submatrix)
{
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
bool isSubmatrix = obj->mat->isSubmatrix();
RETURN_BOOL(isSubmatrix);
}
/**
* Mat->row(y)
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, row)
{
long y;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &y) == FAILURE) {
RETURN_NULL();
}
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *new_obj = Z_PHP_MAT_OBJ_P(&instance);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
Mat im = obj->mat->row(y);
new_obj->mat=new Mat(im);
opencv_mat_update_property_by_c_mat(&instance, new_obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
/**
* Mat->col(x)
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, col)
{
long x;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &x) == FAILURE) {
RETURN_NULL();
}
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *new_obj = Z_PHP_MAT_OBJ_P(&instance);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
Mat im = obj->mat->col(x);
new_obj->mat=new Mat(im);
opencv_mat_update_property_by_c_mat(&instance, new_obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
/**
* Mat->getImageROI(x)
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, get_image_roi)
{
zval *rect_zval;
zval instance;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &rect_zval,opencv_rect_ce) == FAILURE) {
RETURN_NULL();
}
opencv_rect_object *rect_object = Z_PHP_RECT_OBJ_P(rect_zval);
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *new_obj = Z_PHP_MAT_OBJ_P(&instance);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
try {
Mat roi = (*obj->mat)(*rect_object->rect);
new_obj->mat = new Mat(roi);
}catch (Exception exception){
const char* err_msg = exception.what();
opencv_throw_exception(err_msg);//throw exception
RETURN_NULL();
}
opencv_mat_update_property_by_c_mat(&instance, new_obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
ZEND_BEGIN_ARG_INFO_EX(opencv_mat_copy_to_arginfo, 0, 0, 2)
ZEND_ARG_INFO(1, m)
ZEND_ARG_INFO(0, mask)
ZEND_END_ARG_INFO()
/**
* Mat->copyTo(Mat $mat,Mat $mask=NULL)
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, copy_to)
{
zval *m_zval, *mask_zval = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|O", &m_zval, opencv_mat_ce, &mask_zval, opencv_mat_ce) == FAILURE) {
RETURN_NULL();
}
zval *m_real_zval = Z_REFVAL_P(m_zval);
opencv_mat_object *m_object;
if(Z_TYPE_P(m_real_zval) == IS_OBJECT && Z_OBJCE_P(m_real_zval)==opencv_mat_ce){
m_object = Z_PHP_MAT_OBJ_P(m_real_zval);
} else if(Z_TYPE_P(m_real_zval) == IS_NULL){
zval_ptr_dtor(m_real_zval);
zval instance;
Mat dst;
object_init_ex(&instance,opencv_mat_ce);
ZVAL_COPY_VALUE(m_real_zval, &instance);
m_object = Z_PHP_MAT_OBJ_P(m_real_zval);
m_object->mat = new Mat(dst);
}else{
opencv_throw_exception("copy expect param is Mat object or null.");
RETURN_NULL();
}
opencv_mat_object *this_object = Z_PHP_MAT_OBJ_P(getThis());
try {
if(mask_zval != NULL){
opencv_mat_object *mask_object = Z_PHP_MAT_OBJ_P(mask_zval);
this_object->mat->copyTo(*m_object->mat, *mask_object->mat);
}else{
this_object->mat->copyTo(*m_object->mat);
}
opencv_mat_update_property_by_c_mat(m_real_zval, m_object->mat);
}catch (Exception exception){
const char* err_msg = exception.what();
opencv_throw_exception(err_msg);//throw exception
}
RETURN_NULL();
}
/**
* CV\Mat->at
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, at)
{
long row, col, channel;
zval *value_zval = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll|z", &row, &col, &channel, &value_zval) == FAILURE) {
RETURN_NULL();
}
opencv_mat_object *this_object = Z_PHP_MAT_OBJ_P(getThis());
zval *idx_zval;
int *idx;
long return_long_val;
double return_double_val;
idx = new int(2);
idx[0] = row;
idx[1] = col;
opencv_mat_at(this_object->mat, idx, channel, value_zval, &return_long_val, &return_double_val);
switch (this_object->mat->depth()){
case CV_32F:
case CV_64F:
RETURN_DOUBLE(return_double_val);
default:
RETURN_LONG(return_long_val);
}
}
/**
* CV\Mat->atIdx
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, atIdx) // multi dimensions support
{
long channel = 1;
zval *value_zval = NULL;
zval *idx_zval;
int *idx = nullptr;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "a|lz", &idx_zval, &channel, &value_zval) == FAILURE) {
RETURN_NULL();
}
opencv_mat_object *this_object = Z_PHP_MAT_OBJ_P(getThis());
unsigned long idx_count = zend_hash_num_elements(Z_ARRVAL_P(idx_zval));
if (idx_count == 0) {
opencv_throw_exception("array lenght must be >=1");
RETURN_NULL();
} else if (idx_count != this_object->mat->dims) {
opencv_throw_exception("array lenght must be = dims");
RETURN_NULL();
}
idx = new int(idx_count);
zval *array_val_zval;
zend_ulong _h;
ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(idx_zval),_h,array_val_zval){
again:
if(Z_TYPE_P(array_val_zval) == IS_LONG){
//idx.push_back((int)zval_get_long(array_val_zval));
idx[_h] = (int)zval_get_long(array_val_zval);
}else if(Z_TYPE_P(array_val_zval) == IS_REFERENCE){
array_val_zval = Z_REFVAL_P(array_val_zval);
goto again;
} else {
opencv_throw_exception("array value just number.");
RETURN_NULL();
}
}ZEND_HASH_FOREACH_END();
long return_long_val;
double return_double_val;
opencv_mat_at(this_object->mat, idx, channel, value_zval, &return_long_val, &return_double_val);
switch (this_object->mat->depth()){
case CV_32F:
case CV_64F:
RETURN_DOUBLE(return_double_val);
default:
RETURN_LONG(return_long_val);
}
}
ZEND_BEGIN_ARG_INFO_EX(opencv_mat_convert_to_arginfo, 0, 0, 4)
ZEND_ARG_INFO(1, dst)
ZEND_ARG_INFO(0, rtype)
ZEND_ARG_INFO(0, alpha)
ZEND_ARG_INFO(0, beta)
ZEND_END_ARG_INFO()
/**
* CV\Mat->convertTo
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, convert_to){
zval *dst_zval;
long rtype;
double alpha = 1, beta = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl|dd", &dst_zval, &rtype, &alpha, &beta) == FAILURE) {
RETURN_NULL();
}
zval *dst_real_zval = Z_REFVAL_P(dst_zval);
opencv_mat_object *dst_object, *this_object;
if(Z_TYPE_P(dst_real_zval) == IS_OBJECT && Z_OBJCE_P(dst_real_zval)==opencv_mat_ce){
// is Mat object
dst_object = Z_PHP_MAT_OBJ_P(dst_real_zval);
} else{
// isn't Mat object
zval_ptr_dtor(dst_real_zval);
zval instance;
Mat dst;
object_init_ex(&instance,opencv_mat_ce);
ZVAL_COPY_VALUE(dst_real_zval, &instance);// Cover dst_real_zval by Mat object
dst_object = Z_PHP_MAT_OBJ_P(dst_real_zval);
dst_object->mat = new Mat(dst);
}
this_object = Z_PHP_MAT_OBJ_P(getThis());
this_object->mat->convertTo(*dst_object->mat, (int)rtype, alpha, beta);
opencv_mat_update_property_by_c_mat(dst_real_zval,dst_object->mat);
RETURN_NULL();
}
PHP_METHOD(opencv_mat, size)
{
zval instance;
object_init_ex(&instance, opencv_size_ce);
opencv_size_object *size_object = Z_PHP_SIZE_OBJ_P(&instance);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
try {
Size size = obj->mat->size();
size_object->size = new Size(size);
}catch (Exception e){
opencv_throw_exception(e.what());
RETURN_NULL();
}
opencv_size_update_property_by_c_size(&instance, size_object->size);
RETURN_ZVAL(&instance,0,0);
}
/**
* Mat->plus()
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, plus)
{
zval instance;
double number=1;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &number) == FAILURE) {
RETURN_NULL();
}
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *new_obj = Z_PHP_MAT_OBJ_P(&instance);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
new_obj->mat=new Mat(*(obj->mat)*number);
opencv_mat_update_property_by_c_mat(&instance, new_obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
/**
* Mat->divide()
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, divide)
{
zval instance;
double number=1;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &number) == FAILURE) {
RETURN_NULL();
}
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *new_obj = Z_PHP_MAT_OBJ_P(&instance);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
new_obj->mat=new Mat(*(obj->mat)/number);
opencv_mat_update_property_by_c_mat(&instance, new_obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
/**
* Mat->reshape()
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, reshape)
{
zval instance;
long cn;
long rows = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &cn, &rows) == FAILURE) {
RETURN_NULL();
}
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *new_obj = Z_PHP_MAT_OBJ_P(&instance);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(getThis());
Mat im = obj->mat->reshape(cn, rows);
new_obj->mat=new Mat(im);
opencv_mat_update_property_by_c_mat(&instance, new_obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
/**
* //todo mask
* Mat->setTo(Scalar $value)
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, set_to)
{
zval *value_zval;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &value_zval, opencv_scalar_ce) == FAILURE) {
RETURN_NULL();
}
opencv_mat_object *this_obj = Z_PHP_MAT_OBJ_P(getThis());
opencv_scalar_object *value_obj = Z_PHP_SCALAR_OBJ_P(value_zval);
this_obj->mat->setTo(*value_obj->scalar);
RETURN_NULL();
}
/**
* CV\Mat::add()
* @param execute_data
* @param return_value
*/
PHP_METHOD(opencv_mat, add)
{
zval *value1_zval, *value2_zval;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO",
&value1_zval, opencv_mat_ce,
&value2_zval, opencv_mat_ce
) == FAILURE) {
RETURN_NULL();
}
opencv_mat_object *value1_obj = Z_PHP_MAT_OBJ_P(value1_zval);
opencv_mat_object *value2_obj = Z_PHP_MAT_OBJ_P(value2_zval);
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(&instance);
Mat im = *value1_obj->mat + *value2_obj->mat;
obj->mat=new Mat(im);
//update php Mat object property
opencv_mat_update_property_by_c_mat(&instance, obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
PHP_METHOD(opencv_mat, subtract)
{
zval *value1_zval, *value2_zval;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO",
&value1_zval, opencv_mat_ce,
&value2_zval, opencv_mat_ce
) == FAILURE) {
RETURN_NULL();
}
opencv_mat_object *value1_obj = Z_PHP_MAT_OBJ_P(value1_zval);
opencv_mat_object *value2_obj = Z_PHP_MAT_OBJ_P(value2_zval);
zval instance;
object_init_ex(&instance, opencv_mat_ce);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(&instance);
Mat im = *value1_obj->mat - *value2_obj->mat;
obj->mat=new Mat(im);
//update php Mat object property
opencv_mat_update_property_by_c_mat(&instance, obj->mat);
RETURN_ZVAL(&instance,0,0); //return php Mat object
}
/**
* opencv_mat_methods[]
*/
const zend_function_entry opencv_mat_methods[] = {
PHP_ME(opencv_mat, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(opencv_mat, type, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, depth, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, channels, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, empty, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, print, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, size, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, clone, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, ones, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(opencv_mat, zeros, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_MALIAS(opencv_mat, zerosBySize ,zeros_by_size, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_MALIAS(opencv_mat, isContinuous ,is_continuous, NULL, ZEND_ACC_PUBLIC)
PHP_MALIAS(opencv_mat, isSubmatrix ,is_submatrix, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, row, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, col, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, at, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, atIdx, NULL, ZEND_ACC_PUBLIC)
PHP_MALIAS(opencv_mat, getImageROI ,get_image_roi, NULL, ZEND_ACC_PUBLIC)
PHP_MALIAS(opencv_mat, copyTo ,copy_to, opencv_mat_copy_to_arginfo, ZEND_ACC_PUBLIC)
PHP_MALIAS(opencv_mat, convertTo ,convert_to, opencv_mat_convert_to_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, plus, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, divide, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, reshape, NULL, ZEND_ACC_PUBLIC)
PHP_MALIAS(opencv_mat, setTo ,set_to, NULL, ZEND_ACC_PUBLIC)
PHP_ME(opencv_mat, add , NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(opencv_mat, subtract , NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_FE_END
};
/* }}} */
/**
* Mat Class write_property
* @param object
* @param member
* @param value
* @param cache_slot
*/
void opencv_mat_write_property(zval *object, zval *member, zval *value, void **cache_slot){
zend_string *str = zval_get_string(member);
char *memberName=ZSTR_VAL(str);
opencv_mat_object *obj = Z_PHP_MAT_OBJ_P(object);
if(strcmp(memberName, "cols") == 0 && obj->mat->cols!=(int)zval_get_long(value)){
obj->mat->cols=(int)zval_get_long(value);
}else if(strcmp(memberName, "rows") == 0 && obj->mat->rows!=(int)zval_get_long(value)){
obj->mat->rows=(int)zval_get_long(value);
}
zend_string_release(str);//free zend_string not memberName(zend_string->val)
std_object_handlers.write_property(object,member,value,cache_slot);
}
/**
* Mat Init
*/
void opencv_mat_init(void){
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce,OPENCV_NS, "Mat", opencv_mat_methods);
opencv_mat_ce = zend_register_internal_class(&ce);
opencv_mat_ce->create_object = opencv_mat_create_handler;
memcpy(&opencv_mat_object_handlers,
zend_get_std_object_handlers(), sizeof(zend_object_handlers));
opencv_mat_object_handlers.clone_obj = NULL;
opencv_mat_object_handlers.write_property = opencv_mat_write_property;
zend_declare_property_null(opencv_mat_ce,"type",sizeof("type") - 1,ZEND_ACC_PRIVATE);//private Mat->type
opencv_mat_object_handlers.free_obj = opencv_mat_free_obj;
opencv_mat_object_handlers.offset = XtOffsetOf(opencv_mat_object, std);
}