Skip to content

Commit 3de28f1

Browse files
committed
Face detect CV\CascadeClassifier class and some bug fix
1 parent 8cbe8de commit 3de28f1

File tree

9 files changed

+199
-7
lines changed

9 files changed

+199
-7
lines changed

config.m4

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ if test "$PHP_OPENCV" != "no"; then
4343
source/opencv2/opencv_core.cc \
4444
source/opencv2/opencv_imgproc.cc \
4545
source/opencv2/core/opencv_base.cc \
46-
source/opencv2/core/opencv_persistence.cc"
46+
source/opencv2/core/opencv_persistence.cc \
47+
source/opencv2/opencv_objdetect.cc"
4748

4849

4950
PHP_NEW_EXTENSION(opencv, $opencv_source_file, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)

opencv.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ extern "C" {
3838
#include "source/opencv2/opencv_core.h"
3939
#include "source/opencv2/core/opencv_base.h"
4040
#include "source/opencv2/core/opencv_persistence.h"
41+
#include "source/opencv2/opencv_objdetect.h"
4142

4243
/* If you declare any globals in php_opencv.h uncomment this:
4344
ZEND_DECLARE_MODULE_GLOBALS(opencv)
@@ -116,6 +117,7 @@ PHP_MINIT_FUNCTION(opencv)
116117
opencv_core_init(module_number);
117118
opencv_border_types_init(module_number);
118119
opencv_file_storage_init(module_number);
120+
opencv_objdetect_init(module_number);
119121

120122
return SUCCESS;
121123
}

php_opencv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ using namespace cv;
5050

5151
#define OPENCV_NS "CV"
5252

53+
#define OPENCV_CONNECT(text1,text2) text1##text2
54+
55+
56+
//#define OPENCV_BEGIN_ARG_INFO ZEND_BEGIN_ARG_INFO
57+
//#define OPENCV_BEGIN_ARG_INFO_EX ZEND_BEGIN_ARG_INFO_EX
58+
5359
/*
5460
Declare any global variables you may need between the BEGIN
5561
and END macros here:

source/opencv2/core/opencv_persistence.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,4 +264,5 @@ void opencv_file_storage_init(int module_number){
264264

265265
// zend_declare_property_null(opencv_mat_ce,"type",sizeof("type") - 1,ZEND_ACC_PRIVATE);//private Mat->type
266266
// opencv_mat_object_handlers.free_obj = opencv_mat_free_obj;
267+
opencv_file_storage_consts_init(module_number);
267268
}

source/opencv2/core/opencv_type.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ void opencv_rect_free_obj(zend_object *object)
370370
zend_object_std_dtor(object);
371371
}
372372

373+
void opencv_rect_update_property_by_c_rect(zval *z, Rect *rect){
374+
zend_update_property_long(opencv_rect_ce, z, "x", sizeof("x")-1, rect->x);
375+
zend_update_property_long(opencv_rect_ce, z, "y", sizeof("y")-1, rect->y);
376+
zend_update_property_long(opencv_rect_ce, z, "width", sizeof("width")-1, rect->width);
377+
zend_update_property_long(opencv_rect_ce, z, "height", sizeof("height")-1, rect->height);
378+
}
373379

374380
/**
375381
* Rect __construct
@@ -385,11 +391,7 @@ PHP_METHOD(opencv_rect, __construct)
385391
opencv_rect_object *obj = Z_PHP_RECT_OBJ_P(getThis());
386392
Rect rect = Rect((int)x, (int)y, (int)width, (int)height);
387393
obj->rect = new Rect(rect);
388-
389-
zend_update_property_long(opencv_rect_ce, getThis(), "x", sizeof("x")-1, obj->rect->x);
390-
zend_update_property_long(opencv_rect_ce, getThis(), "y", sizeof("y")-1, obj->rect->y);
391-
zend_update_property_long(opencv_rect_ce, getThis(), "width", sizeof("width")-1, obj->rect->width);
392-
zend_update_property_long(opencv_rect_ce, getThis(), "height", sizeof("height")-1, obj->rect->height);
394+
opencv_rect_update_property_by_c_rect(getThis(),obj->rect);
393395
}
394396

395397

source/opencv2/core/opencv_type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,7 @@ static inline opencv_rect_object* get_rect_obj(zend_object *obj) {
5959
return (opencv_rect_object*)((char*)(obj) - XtOffsetOf(opencv_rect_object, std));
6060
}
6161

62+
void opencv_rect_update_property_by_c_rect(zval *z, Rect *rect);
63+
6264
void opencv_scalar_update_property_by_c_scalar(zval *z,Scalar *scalar);
6365
#endif //OPENCV_OPENCV_TYPE_H

source/opencv2/opencv_core.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ PHP_FUNCTION(opencv_add_weighted){
107107
RETURN_NULL();
108108
}
109109

110-
#define OPENCV_CONNECT(text1,text2) text1##text2
111110

112111
/**
113112
* CV\split

source/opencv2/opencv_objdetect.cc

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
2+
#include "../../php_opencv.h"
3+
#include <opencv2/objdetect.hpp>
4+
#include "opencv_objdetect.h"
5+
#include "core/opencv_type.h"
6+
#include "core/opencv_mat.h"
7+
8+
zend_class_entry *opencv_cascade_classifier_ce;
9+
10+
zend_object_handlers opencv_cascade_classifier_object_handlers;
11+
12+
/**
13+
* @param type
14+
* @return
15+
*/
16+
zend_object* opencv_cascade_classifier_create_handler(zend_class_entry *type)
17+
{
18+
int size = sizeof(opencv_cascade_classifier_object);
19+
opencv_cascade_classifier_object *obj = (opencv_cascade_classifier_object *)ecalloc(1,size);
20+
memset(obj, 0, sizeof(opencv_cascade_classifier_object));
21+
zend_object_std_init(&obj->std, type);
22+
object_properties_init(&obj->std, type);
23+
obj->std.ce = type;
24+
obj->std.handlers = &opencv_cascade_classifier_object_handlers;
25+
return &obj->std;
26+
}
27+
28+
/**
29+
* CascadeClassifier __construct
30+
* @param execute_data
31+
* @param return_value
32+
*/
33+
PHP_METHOD(opencv_cascade_classifier, __construct)
34+
{
35+
opencv_cascade_classifier_object *obj = Z_PHP_CASCADE_CLASSIFIER_OBJ_P(getThis());
36+
obj->cascadeClassifier = new CascadeClassifier();
37+
}
38+
39+
PHP_METHOD(opencv_cascade_classifier, load)
40+
{
41+
char *filename;
42+
long filename_len;
43+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &filename, &filename_len) == FAILURE) {
44+
RETURN_NULL();
45+
}
46+
opencv_cascade_classifier_object *this_obj = Z_PHP_CASCADE_CLASSIFIER_OBJ_P(getThis());
47+
bool result = this_obj->cascadeClassifier->load(filename);
48+
RETURN_BOOL(result);
49+
}
50+
51+
ZEND_BEGIN_ARG_INFO_EX(opencv_cascade_classifier_detect_multi_scale_arginfo, 0, 0, 7)
52+
ZEND_ARG_INFO(0, image)
53+
ZEND_ARG_INFO(1, objects)
54+
ZEND_ARG_INFO(0, scaleFactor)
55+
ZEND_ARG_INFO(0, minNeighbors)
56+
ZEND_ARG_INFO(0, flags)
57+
ZEND_ARG_INFO(0, minSize)
58+
ZEND_ARG_INFO(0, maxSize)
59+
ZEND_END_ARG_INFO()
60+
61+
/**
62+
* CascadeClassifier->detectMultiScale function
63+
* @param execute_data
64+
* @param return_value
65+
*/
66+
PHP_METHOD(opencv_cascade_classifier, detect_multi_scale)
67+
{
68+
zval *image_zval, *objects_zval, *min_size_zval = NULL, *max_size_zval = NULL;
69+
double scale_factor = 1.1;
70+
long min_neighbors = 3, flags = 0;
71+
Size min_size = Size(), max_size = Size();
72+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz|dllOO",
73+
&image_zval, opencv_mat_ce,
74+
&objects_zval, &scale_factor, &min_neighbors, &flags,
75+
&min_size_zval, opencv_size_ce,
76+
&max_size_zval, opencv_size_ce
77+
78+
) == FAILURE) {
79+
RETURN_NULL();
80+
}
81+
std::vector<Rect> objects;
82+
opencv_mat_object *image_object = Z_PHP_MAT_OBJ_P(image_zval);
83+
opencv_cascade_classifier_object *this_obj = Z_PHP_CASCADE_CLASSIFIER_OBJ_P(getThis());
84+
if(min_size_zval != NULL){
85+
opencv_size_object *min_size_object = Z_PHP_SIZE_OBJ_P(min_size_zval);
86+
min_size = *min_size_object->size;
87+
}
88+
89+
if(max_size_zval != NULL){
90+
opencv_size_object *max_size_object = Z_PHP_SIZE_OBJ_P(max_size_zval);
91+
max_size = *max_size_object->size;
92+
}
93+
94+
this_obj->cascadeClassifier->detectMultiScale(
95+
*(image_object->mat), objects, scale_factor,
96+
(int)min_neighbors, (int)flags,
97+
min_size, max_size);
98+
99+
zval *objects_real_zval = Z_REFVAL_P(objects_zval);
100+
zval instance;
101+
array_init(&instance);
102+
for(unsigned long i=0; i < objects.size(); i++){
103+
zval OPENCV_CONNECT(zval,i);
104+
Rect OPENCV_CONNECT(rect,i);
105+
opencv_rect_object *OPENCV_CONNECT(rect_object,i);
106+
object_init_ex(&OPENCV_CONNECT(zval,i), opencv_rect_ce);
107+
OPENCV_CONNECT(rect_object,i) = Z_PHP_RECT_OBJ_P(&OPENCV_CONNECT(zval,i));
108+
OPENCV_CONNECT(rect,i) = objects.at(i);
109+
OPENCV_CONNECT(rect_object,i)->rect = new Rect(OPENCV_CONNECT(rect,i));
110+
opencv_rect_update_property_by_c_rect(&OPENCV_CONNECT(zval,i), OPENCV_CONNECT(rect_object,i)->rect);
111+
add_next_index_zval(&instance,&OPENCV_CONNECT(zval,i));
112+
113+
}
114+
ZVAL_COPY_VALUE(objects_real_zval, &instance);
115+
RETURN_NULL();
116+
}
117+
118+
/**
119+
* opencv_cascade_classifier_methods[]
120+
*/
121+
const zend_function_entry opencv_cascade_classifier_methods[] = {
122+
PHP_ME(opencv_cascade_classifier, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
123+
PHP_ME(opencv_cascade_classifier, load, NULL, ZEND_ACC_PUBLIC)
124+
PHP_MALIAS(opencv_cascade_classifier, detectMultiScale ,detect_multi_scale, opencv_cascade_classifier_detect_multi_scale_arginfo, ZEND_ACC_PUBLIC)
125+
PHP_FE_END
126+
};
127+
/* }}} */
128+
129+
void opencv_cascade_classifier_free_obj(zend_object *object)
130+
{
131+
opencv_cascade_classifier_object *obj;
132+
obj = get_cascade_classifier_obj(object);
133+
delete obj->cascadeClassifier;
134+
zend_object_std_dtor(object);
135+
}
136+
137+
138+
/**
139+
* opencv_cascade_classifier_init
140+
* @param module_number
141+
*/
142+
void opencv_cascade_classifier_init(int module_number){
143+
zend_class_entry ce;
144+
INIT_NS_CLASS_ENTRY(ce,OPENCV_NS, "CascadeClassifier", opencv_cascade_classifier_methods);
145+
opencv_cascade_classifier_ce = zend_register_internal_class(&ce);
146+
147+
opencv_cascade_classifier_ce->create_object = opencv_cascade_classifier_create_handler;
148+
memcpy(&opencv_cascade_classifier_object_handlers,
149+
zend_get_std_object_handlers(), sizeof(zend_object_handlers));
150+
opencv_cascade_classifier_object_handlers.clone_obj = NULL;
151+
// opencv_cascade_classifier_object_handlers.write_property = opencv_mat_write_property;
152+
opencv_cascade_classifier_object_handlers.free_obj = opencv_cascade_classifier_free_obj;
153+
}
154+
155+
void opencv_objdetect_init(int module_number){
156+
opencv_cascade_classifier_init(module_number);
157+
}

source/opencv2/opencv_objdetect.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef OPENCV_OBJDETECT_H
2+
#define OPENCV_OBJDETECT_H
3+
4+
#include "../../php_opencv.h"
5+
#include <opencv2/objdetect.hpp>
6+
7+
extern zend_class_entry *opencv_cascade_classifier_ce;
8+
9+
#define Z_PHP_CASCADE_CLASSIFIER_OBJ_P(zv) get_cascade_classifier_obj(Z_OBJ_P(zv))
10+
11+
typedef struct _opencv_cascade_classifier_object{
12+
zend_object std;
13+
CascadeClassifier *cascadeClassifier;
14+
}opencv_cascade_classifier_object;
15+
16+
extern void opencv_objdetect_init(int module_number);
17+
18+
static inline opencv_cascade_classifier_object* get_cascade_classifier_obj(zend_object *obj) {
19+
return (opencv_cascade_classifier_object*)((char*)(obj) - XtOffsetOf(opencv_cascade_classifier_object, std));
20+
}
21+
22+
#endif //OPENCV_OBJDETECT_H

0 commit comments

Comments
 (0)