-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblob_util.cpp
114 lines (93 loc) · 3.4 KB
/
blob_util.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "blob_util.h"
extern bool OUTPUT_INTERMEDIATE_RESULTS;
double get_blobs_size(CBlobResult blobs)
{
double blobs_size = 0;
for (int i = 0; i < blobs.GetNumBlobs(); i++) {
CBlob b = blobs.GetBlob(i);
blobs_size += b.Area();
}
return blobs_size;
}
double get_min_distace_to_blob(int * point, IplImage * bin_img, CBlobResult blobs)
{
double distance;
int n = blobs.GetNumBlobs();
// when the object is not around eye gaze point.
if (blobs.GetNumBlobs() < 1) {
// distance = 2 * (bin_img->height + bin_img->width);
return -1;
}
CvScalar s;
s=cvGet2D(bin_img,point[1],point[0]); // get the pixel value. Please note order of parameters.
if (s.val[0] >= 128) {
distance = 0;
return distance;
}
IplImage * tmp = cvCreateImage( cvGetSize(bin_img), IPL_DEPTH_32F, bin_img->nChannels); // the deapth couldn't be 8U if it is the destination of cvLaplace.
cvLaplace(bin_img, tmp, 1);
// cvSobel(bin_img, tmp, 1, 0, 3);
IplImage * edge_img = cvCreateImage( cvGetSize(tmp), IPL_DEPTH_8U, 1);
cvThreshold(tmp, edge_img, 100, 255, CV_THRESH_BINARY);
if (OUTPUT_INTERMEDIATE_RESULTS) {
cvSaveImage("laplace.jpg", edge_img);
}
int step = edge_img->widthStep / sizeof(unsigned char );
unsigned char * data = (unsigned char *) edge_img->imageData;
distance = 2 * (bin_img->height + bin_img->width); // initial distance is a large number.
for (int i = 0; i < blobs.GetNumBlobs(); i++ ) {
CBlob b = blobs.GetBlob(i);
CvRect box = b.GetBoundingBox();
for (int j=box.y; j<box.y+box.height; j+=2) {
for (int k=box.x; k<box.x+box.width; k+=2) {
int d = data[j*step +k];
if (d) {
double this_dist = sqrt(double((j-point[1]) * (j-point[1]) + (k-point[0])*(k-point[0])));
if (this_dist < distance)
distance = this_dist;
}
}
}
}
cvReleaseImage(&tmp);
cvReleaseImage(&edge_img);
return distance;
}
CvRect * detect_blob(IplImage * binImg, int blob_size_threshold, int * numRect)
{
//////////////////////////////////////////////////////////////
// get blobs and filter them using its area
/////////////////////////////////////////////////////////////
CBlobResult blobs;
// find blobs in thresholded image
blobs = CBlobResult(binImg, (IplImage*)0, 0);
// exclude the ones smaller than blob_size_threshold
blobs.Filter( blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, blob_size_threshold );
// printf("blob number: %d\n", blobs.GetNumBlobs() );
int n = blobs.GetNumBlobs();
*numRect = n;
//CvRect * boxes = new CvRect[n];
int maxArea = 0;
int maxIdx = -1;
for (int j=0; j<n; j++) { // find the size of largest blob.
CBlob cb = blobs.GetBlob(j);
int thisArea = cb.Area();
if (thisArea > maxArea) {
maxArea = thisArea;
maxIdx = j;
}
// boxes[j] = cb.GetBoundingBox();
// printf("blob %d: %d %d %d %d, size: %lf\n", j, boxes[j].x, boxes[j].y, boxes[j].width, boxes[j].height, cb.Area());
}
// only leave the largest blob.
blobs.Filter( blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, maxArea);
n = blobs.GetNumBlobs();
*numRect = n;
CvRect * boxes = new CvRect[n];
for (int j=0; j<n; j++) { // find the size of largest blob.
CBlob cb = blobs.GetBlob(j);
boxes[j] = cb.GetBoundingBox();
// printf("blob %d: %d %d %d %d, size: %lf\n", j, boxes[j].x, boxes[j].y, boxes[j].width, boxes[j].height, cb.Area());
}
return boxes;
}