-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConsensusCellMask.cpp
144 lines (107 loc) · 2.92 KB
/
ConsensusCellMask.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <Rcpp.h>
//#include <math.h>
using namespace Rcpp;
struct obj_pixel{
int i;
int j;
int obj_id; //object id
double prob; //object prob
char marker;
};
bool compare_obj_pixel(const obj_pixel &a, const obj_pixel &b){
if(a.prob == b.prob){
return a.obj_id > b.obj_id; //give preference to obj with higher id
}else{
return a.prob > b.prob;
}
}
// fill pixel with object probability mean
void average_obj_prob(NumericMatrix s, NumericMatrix p){
int nrow = s.nrow(), ncol=s.ncol();
double obj_prob_sum[nrow*ncol];
int pix_count[nrow*ncol];
// loop through every pixel of the probability map
for(int i=0; i < nrow; i++){
for(int j=0; j < ncol; j++){
int id = s(i,j);
if(id > 0){
obj_prob_sum[id]+= p(i,j);
pix_count[id]++;
}
}
}
for(int i=0; i<nrow; i++){
for(int j=0; j<ncol; j++){
int id = s(i,j);
double obj_mean = obj_prob_sum[id]/pix_count[id];
if(id > 0){
p(i,j) = obj_mean;
}
}
}
}
// [[Rcpp::export]]
NumericMatrix cpp_segmentation_merge(SEXP segA, SEXP probA, SEXP segB, SEXP probB){
NumericMatrix mSA(segA);
NumericMatrix mPA(probA);
NumericMatrix mSB(segB);
NumericMatrix mPB(probB);
// TODO:
// Check that all matrices have the same dimensions (going outside bounds will crash!)
if( (mSA.ncol() != mPA.ncol()) || (mSA.nrow() != mPA.nrow())){
throw std::invalid_argument("Two matrices are not of the same dimension!");
}
int nb_row = mSA.nrow(), nb_col=mSA.ncol();
// Init result matrix
NumericMatrix mRES(nb_row, nb_col);
// Init vector of pixels
std::vector<obj_pixel> vPix;
//average probability
average_obj_prob(mSA, mPA);
average_obj_prob(mSB, mPB);
// Add pixels to vector
for(int i=0; i< nb_row; i++){
for(int j=0; j< nb_col; j++){
obj_pixel pa = obj_pixel();
pa.prob = mPA(i,j);
pa.obj_id = mSA(i,j);
pa.i = i; pa.j = j;
pa.marker='A';
vPix.push_back(pa);
obj_pixel pb = obj_pixel();
pb.prob = mPB(i,j);
pb.obj_id = mSB(i,j);
pb.i = i; pb.j = j;
pb.marker='B';
vPix.push_back(pb);
}
}
//Rcout<<"init vector done"<<"\n";
std::sort(vPix.begin(), vPix.end(), compare_obj_pixel);
//loop through pixels
int k = 0;
while(k < vPix.size()){
obj_pixel& p = vPix[k];
int obj_id = p.obj_id; //current obj_id
bool conflict = false;
// check conflict for current object
int k2 = k;
while(k2 < vPix.size() && vPix[k2].obj_id == obj_id){
if(mRES(vPix[k2].i , vPix[k2].j) != 0){
conflict = true;
}
k2++;
}
// if no conflict, we add this object
if(!conflict){
while(k < vPix.size() && k < k2){
mRES(vPix[k].i, vPix[k].j) = (vPix[k].marker == 'A')? 2:3;
k++;
}
}
else{
k = k2; //skip this object
}
}
return(mRES);
}