Skip to content

Commit b6bf3a9

Browse files
committed
to train LCHF, need another 8GB RAM...
1 parent 32bd1ea commit b6bf3a9

File tree

5 files changed

+148
-111
lines changed

5 files changed

+148
-111
lines changed

LCHF_test.py

Lines changed: 82 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ def nms(dets, thresh):
119119
if scene_ids:
120120
scene_ids_curr = set(scene_ids_curr).intersection(scene_ids)
121121

122-
# mode = 'render_train'
123-
mode = 'test'
122+
mode = 'render_train'
123+
# mode = 'test'
124124

125125
base_path = join(dp['base_path'], 'LCHF')
126-
train_from_radius = 1000
126+
train_from_radius = 500
127127
if mode == 'render_train':
128128
start_time = time.time()
129129
visual = True
@@ -160,7 +160,7 @@ def nms(dets, thresh):
160160
# Sample views
161161
views, views_level = view_sampler.sample_views(min_n_views, radius,
162162
azimuth_range, elev_range,
163-
tilt_range=(0, 2*math.pi), tilt_step=0.1*math.pi)
163+
tilt_range=(-math.pi/2, math.pi/2), tilt_step=0.2*math.pi)
164164
print('Sampled views: ' + str(len(views)))
165165

166166
# Render the object model from all the views
@@ -210,41 +210,37 @@ def nms(dets, thresh):
210210
cols = depth.shape[1]
211211
# have read rgb, depth, pose, obj_bb, obj_id, bbox, mask here
212212

213-
# 5 box
214-
for i in range(5):
215-
j = (i - (i%2))/2
216-
217-
# offset, width, height, depth
218-
offset1 = [int(i%2*cols/2), int(j*rows/2), int(cols / 2), int(rows / 2)]
219-
if i == 4:
220-
offset1 = [int(cols / 4), int(rows / 4), int(cols / 2), int(rows / 2), t[2]]
221-
222-
rgb1 = rgb[offset1[1]:(offset1[1] + offset1[3]), offset1[0]:(offset1[0] + offset1[2]), :]
223-
depth1 = depth[offset1[1]:(offset1[1] + offset1[3]), offset1[0]:(offset1[0] + offset1[2])]
224-
225-
visualized = False
226-
if visualized:
227-
rgb_ = np.copy(rgb)
228-
cv2.rectangle(rgb_, (offset1[0], offset1[1]),
229-
(offset1[0] + offset1[2], offset1[1] + offset1[3]), (0, 0, 255), 1)
230-
cv2.imshow('rgb', rgb_)
231-
cv2.imshow('rgb1', rgb1)
232-
cv2.waitKey(0)
233-
234-
LCHF_linemod_feat = cxxLCHF_pybind.Linemod_feature(rgb1, depth1)
235-
if LCHF_linemod_feat.constructEmbedding(): # extract template OK
236-
LCHF_linemod_feat.constructResponse() # extract response map for simi func
237-
else:
238-
# print('points not enough')
239-
continue # no enough points for template extraction, pass
240-
241-
LCHF_linemod_feats.append(LCHF_linemod_feat) # record feature
242-
243-
LCHF_info = cxxLCHF_pybind.Info()
244-
LCHF_info.rpy = (rotationMatrixToEulerAngles(R)).astype(np.float32) # make sure consistent
245-
LCHF_info.t = (np.array(offset1)).astype(np.float32)
246-
LCHF_info.id = str(obj_id)
247-
LCHF_infos.append(LCHF_info) # record info
213+
# 5x5 cm patch, stride 5, assume 1pix = 1mm in around 500mm depth
214+
stride = 10
215+
for row in range(0, rows - 50, stride):
216+
for col in range(0, cols - 50, stride):
217+
offset1 = [col, row, 50, 50]
218+
rgb1 = rgb[offset1[1]:(offset1[1] + offset1[3]), offset1[0]:(offset1[0] + offset1[2]), :]
219+
depth1 = depth[offset1[1]:(offset1[1] + offset1[3]), offset1[0]:(offset1[0] + offset1[2])]
220+
221+
visualized = False
222+
if visualized:
223+
rgb_ = np.copy(rgb)
224+
cv2.rectangle(rgb_, (offset1[0], offset1[1]),
225+
(offset1[0] + offset1[2], offset1[1] + offset1[3]), (0, 0, 255), 1)
226+
cv2.imshow('rgb', rgb_)
227+
cv2.imshow('rgb1', rgb1)
228+
cv2.waitKey(0)
229+
230+
LCHF_linemod_feat = cxxLCHF_pybind.Linemod_feature(rgb1, depth1)
231+
if LCHF_linemod_feat.constructEmbedding(): # extract template OK
232+
LCHF_linemod_feat.constructResponse() # extract response map for simi func
233+
else:
234+
# print('points not enough')
235+
continue # no enough points for template extraction, pass
236+
237+
LCHF_linemod_feats.append(LCHF_linemod_feat) # record feature
238+
239+
LCHF_info = cxxLCHF_pybind.Info()
240+
LCHF_info.rpy = (rotationMatrixToEulerAngles(R)).astype(np.float32) # make sure consistent
241+
LCHF_info.t = (np.array(offset1)).astype(np.float32)
242+
LCHF_info.id = str(obj_id)
243+
LCHF_infos.append(LCHF_info) # record info
248244

249245
del rgb, depth, mask
250246

@@ -258,7 +254,6 @@ def nms(dets, thresh):
258254
forest = cxxLCHF_pybind.lchf_model_train(LCHF_linemod_feats, LCHF_infos)
259255
cxxLCHF_pybind.lchf_model_saveForest(forest, base_path)
260256

261-
262257
elapsed_time = time.time() - start_time
263258
print('train time: {}\n'.format(elapsed_time))
264259

@@ -307,7 +302,7 @@ def nms(dets, thresh):
307302

308303
rows = depth.shape[0]
309304
cols = depth.shape[1]
310-
stride = 3
305+
stride = 5
311306

312307
# should be max_bbox * render_depth/max_scene_depth
313308
width = 50 # bigger is OK, top left corner should align obj
@@ -345,47 +340,66 @@ def nms(dets, thresh):
345340
start_time = time.time()
346341
print('forest predict time: {}'.format(elapsed_time))
347342

348-
# voting isn't working well, and
349-
# should meanshift the leaf first
350-
num_x_bins = int(cols/20)
351-
num_y_bins = int(rows/20)
343+
steps = 10
344+
num_x_bins = int(cols/steps)
345+
num_y_bins = int(rows/steps)
352346
num_angle_bins = 10
353347

348+
print('x_bins: {}, y_bins: {}'.format(num_x_bins, num_y_bins))
349+
354350
votes = np.zeros(shape=(num_x_bins, num_y_bins, num_angle_bins, num_angle_bins, num_angle_bins),
355351
dtype=np.float32)
356352

353+
voted_ids = {}
354+
357355
for scene_i in range(len(leaf_of_trees_of_scene)):
358356
trees_of_scene = leaf_of_trees_of_scene[scene_i]
359357
roi = rois[scene_i]
358+
360359
for tree_i in range(len(trees_of_scene)):
361360
leaf_i = trees_of_scene[tree_i]
362-
leaf_map = leaf_feats_map[tree_i]
363-
predicted_ids = leaf_map[leaf_i]
364-
for id_ in predicted_ids:
365-
info = LCHF_infos[id_]
366-
offset = info.t
367-
offset_x = offset[0] * train_from_radius / roi[4]
368-
offset_y = offset[1] * train_from_radius / roi[4]
369-
370-
x = int((roi[0] - offset_x) / 20)
371-
y = int((roi[1] - offset_y) / 20)
372-
theta0 = int(info.rpy[0] / 2 / 3.14 * num_angle_bins)
373-
theta1 = int(info.rpy[1] / 2 / 3.14 * num_angle_bins)
374-
theta2 = int(info.rpy[2] / 2 / 3.14 * num_angle_bins)
375-
376-
# votes[x-1:x+1, y-1:y+1, theta0-1:theta0+1, theta1-1:theta1+1, theta2-1:theta2+1] \
377-
# += 1.0/len(predicted_ids)/len(trees_of_scene)
378-
votes[x, y, theta0, theta1, theta2] \
379-
+= 1.0/len(predicted_ids)/len(trees_of_scene)
361+
362+
# if leaf_i has predicted
363+
if (tree_i, leaf_i) in voted_ids:
364+
votes += voted_ids[(tree_i, leaf_i)]
365+
else:
366+
# leaf_i votes
367+
votes_local = np.zeros(
368+
shape=(num_x_bins, num_y_bins, num_angle_bins, num_angle_bins, num_angle_bins),
369+
dtype=np.float32)
370+
371+
leaf_map = leaf_feats_map[tree_i]
372+
predicted_ids = leaf_map[leaf_i]
373+
for id_ in predicted_ids:
374+
info = LCHF_infos[id_]
375+
offset = info.t
376+
offset_x = offset[0] * train_from_radius / roi[4]
377+
offset_y = offset[1] * train_from_radius / roi[4]
378+
379+
x = int((roi[0] - offset_x) / steps)
380+
y = int((roi[1] - offset_y) / steps)
381+
theta0 = int(info.rpy[0] / 2 / 3.14 * num_angle_bins)
382+
theta1 = int(info.rpy[1] / 2 / 3.14 * num_angle_bins)
383+
theta2 = int(info.rpy[2] / 2 / 3.14 * num_angle_bins)
384+
385+
# votes[x-1:x+1, y-1:y+1, theta0-1:theta0+1, theta1-1:theta1+1, theta2-1:theta2+1] \
386+
# += 1.0/len(predicted_ids)/len(trees_of_scene)
387+
votes_local[x, y, theta0, theta1, theta2] \
388+
+= 1.0 / len(predicted_ids) / len(trees_of_scene)
389+
votes += votes_local
390+
391+
# cache
392+
voted_ids[(tree_i, leaf_i)] = votes_local
380393

381394
votes_sort_idx = np.dstack(np.unravel_index(np.argsort(votes.ravel()), votes.shape))
382395

383-
top10 = 100
396+
top10 = 10
397+
if top10>votes_sort_idx.shape[1]:
398+
top10 = votes_sort_idx.shape[1]
399+
400+
print('top {}'.format(top10))
384401
for i in range(1, top10):
385-
if 19 > votes_sort_idx[0, -i, 0] > 1 and 19 > votes_sort_idx[0, -i, 1] > 1:
386-
cv2.circle(rgb, (votes_sort_idx[0, -i, 1]*20, votes_sort_idx[0, -i, 0]*20), 2, (0, 0, 255), -1)
387-
print('votes_sort_idx: {}, votes: {}'.format(votes_sort_idx[0, -i, :],
388-
votes[tuple(votes_sort_idx[0, -i, :])]))
402+
cv2.circle(rgb, (votes_sort_idx[0, -i, 0]*steps, votes_sort_idx[0, -i, 1]*steps), 4, (0, 255-i*2, 0), -1)
389403

390404
elapsed_time = time.time() - start_time
391405
print('voting time: {}'.format(elapsed_time))

cxxLCHF/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 2.8)
22
set (CMAKE_CXX_STANDARD 14)
33
project(cxxLCHF_pybind)
44

5-
SET(CMAKE_BUILD_TYPE "Debug")
6-
#SET(CMAKE_BUILD_TYPE "Release")
5+
#SET(CMAKE_BUILD_TYPE "Debug")
6+
SET(CMAKE_BUILD_TYPE "Release")
77
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb -fPIC")
88
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -fPIC")
99

cxxLCHF/lchf.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -719,28 +719,40 @@ float Linemod_feature::similarity(const Linemod_feature &other) const{
719719
float score = 0;
720720
auto& rgb_res = other.embedding.rgb_response;
721721

722-
// cv::Mat templ = cv::Mat::zeros(500, 500, CV_8UC1);
723-
// cv::Mat templ2 = cv::Mat::zeros(500, 500, CV_8UC1);
724-
for(auto element: embedding.rgb_embedding){
722+
auto get_depth = [](const cv::Mat& depth, int y, int x){
723+
int ker_size = 5;
724+
int x_tl = x - ker_size/2;
725+
if(x_tl<0) x_tl = 0;
726+
int y_tl = y - ker_size/2;
727+
if(y_tl<0) y_tl = 0;
728+
729+
int width = ker_size;
730+
if(width>depth.cols-x_tl) width = depth.cols-x_tl;
731+
int height = ker_size;
732+
if(height>depth.rows-y_tl) height = depth.rows-y_tl;
725733

726-
// templ.at<uchar>(element.y+100, element.x+100) = 255;
734+
cv::Rect roi(x_tl, y_tl, width, height);
735+
int ave_depth = int(cv::sum(depth(roi))[0]/cv::countNonZero(depth(roi)));
736+
737+
return ave_depth;
738+
};
739+
740+
for(auto element: embedding.rgb_embedding){
727741

728742
if(other.embedding.center_dep>0 && embedding.center_dep>0){
729743
int normalize_x = element.x*embedding.center_dep/other.embedding.center_dep;
730744
int normalize_y = element.y*embedding.center_dep/other.embedding.center_dep;
731745

732-
// templ2.at<uchar>(normalize_y+100, normalize_x+100) = 255;
733-
734746
if(element.y>=depth.rows || element.x>=depth.cols ||
735747
normalize_y>=other.depth.rows || normalize_x>=other.depth.cols){
736748
continue;
737749
}
738750

739-
// int z_1 = embedding.center_dep-get_depth(depth, element.y, element.x);
740-
// int z_2 = other.embedding.center_dep-get_depth(other.depth, normalize_y,normalize_x);
751+
int z_1 = embedding.center_dep-get_depth(depth, element.y, element.x);
752+
int z_2 = other.embedding.center_dep-get_depth(other.depth, normalize_y,normalize_x);
741753

742-
// bool valid = std::abs(z_1-z_2) < embedding.z_check;
743-
// if(valid)
754+
bool valid = std::abs(z_1-z_2) < embedding.z_check;
755+
if(valid)
744756
{
745757
auto response = rgb_res[element.label];
746758
score += response.at<uchar>(normalize_y,normalize_x);
@@ -749,11 +761,6 @@ float Linemod_feature::similarity(const Linemod_feature &other) const{
749761
}
750762
}
751763

752-
// std::cout << embedding.rgb_embedding.size() << std::endl;
753-
// cv::imshow("t1", templ);
754-
// cv::imshow("t2", templ2);
755-
// cv::waitKey(0);
756-
757764
auto& dep_res = other.embedding.dep_response;
758765
for(auto element: embedding.depth_embedding){
759766
if(other.embedding.center_dep>0 && embedding.center_dep>0){
@@ -765,11 +772,11 @@ float Linemod_feature::similarity(const Linemod_feature &other) const{
765772
continue;
766773
}
767774

768-
// int z_1 = embedding.center_dep-get_depth(depth, element.y, element.x);
769-
// int z_2 = other.embedding.center_dep-get_depth(other.depth, normalize_y,normalize_x);
775+
int z_1 = embedding.center_dep-get_depth(depth, element.y, element.x);
776+
int z_2 = other.embedding.center_dep-get_depth(other.depth, normalize_y,normalize_x);
770777

771-
// bool valid = std::abs(z_1-z_2) < embedding.z_check;
772-
// if(valid)
778+
bool valid = std::abs(z_1-z_2) < embedding.z_check;
779+
if(valid)
773780
{
774781
auto response = dep_res[element.label];
775782
score += response.at<uchar>(normalize_y,normalize_x);

cxxLCHF/lchf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Linemod_embedding {
2626
distance_threshold(2000),
2727
difference_threshold(50),
2828
extract_threshold(2),
29-
z_check(100){}
29+
z_check(200){}
3030
float weak_threshold, strong_threshold;
3131
int num_features, distance_threshold, difference_threshold, extract_threshold;
3232
class element {

cxxLCHF/test.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,36 @@ void API_test(){
163163
std::vector<std::vector<int>> rois;
164164
for(int x=0; x<cols-width-2*stride; x+=stride){
165165
for(int y=0; y<rows-height-2*stride; y+=stride){
166-
std::vector<int> roi = {x, y, width, height, dep_x, dep_y};
166+
167+
int dep_value = depth.at<ushort>(y+dep_y, x+dep_x);
168+
if(dep_value==0) continue;
169+
std::vector<int> roi = {x, y, width, height, dep_value};
167170
rois.push_back(roi);
168171
}
169172
}
170-
171173
auto scene_feats = lchf_model::get_feats_from_scene(rgb, depth, rois);
172-
173174
auto leaf_of_trees_of_scene = lchf_model::predict(forest, feats, scene_feats);
175+
auto leaf_feats_map = lchf_model::getLeaf_feats_map(forest);
176+
177+
std::map<int, double> bg_prob;
178+
for(int scene_iter=0; scene_iter<leaf_of_trees_of_scene.size(); scene_iter++){
179+
auto& trees_of_scene = leaf_of_trees_of_scene[scene_iter];
180+
auto& roi = rois[scene_iter];
181+
for(int tree_iter=0; tree_iter<trees_of_scene.size(); tree_iter++){
182+
auto& leaf_iter = trees_of_scene[tree_iter];
183+
auto& leaf_map = leaf_feats_map[tree_iter];
184+
auto& predicted_ids = leaf_map[leaf_iter];
185+
186+
for(auto id: predicted_ids){
187+
if(bg_prob.find(id) == bg_prob.end()){
188+
bg_prob[id] = 1.0/predicted_ids.size()
189+
/trees_of_scene.size()/leaf_of_trees_of_scene.size();
190+
}else{
191+
bg_prob[id] += 1.0/predicted_ids.size()
192+
/trees_of_scene.size()/leaf_of_trees_of_scene.size();
193+
}
194+
}
174195

175-
auto first_one = leaf_of_trees_of_scene[0];
176-
for(auto& leaf_of_trees: leaf_of_trees_of_scene){
177-
if(leaf_of_trees!=first_one){
178-
std::cout << "found it!" << std::endl;
179-
first_one = leaf_of_trees;
180196
}
181197
}
182198
}
@@ -209,21 +225,21 @@ void simi_test(){
209225
// std::cout << "\nself simi(should be 100): " << simi << std::endl;
210226
// }
211227

212-
{ // result is around 75, 55-95
213-
cv::Mat rgb_2, depth_2;
214-
pyrDown(rgb(bbox), rgb_2);
228+
// { // result is around 75, 55-95
229+
// cv::Mat rgb_2, depth_2;
230+
// pyrDown(rgb(bbox), rgb_2);
215231

216-
imshow("rgb_2", rgb_2);
232+
// imshow("rgb_2", rgb_2);
217233

218-
pyrDown(depth(bbox), depth_2);
219-
depth_2 *= 2;
234+
// pyrDown(depth(bbox), depth_2);
235+
// depth_2 *= 2;
220236

221-
Linemod_feature f_2(rgb_2, depth_2);
222-
f_2.constructResponse();
223-
float simi = features[features.size()-1]
224-
.similarity(f_2);
225-
std::cout << "\ndiff depth simi: " << simi << std::endl;
226-
}
237+
// Linemod_feature f_2(rgb_2, depth_2);
238+
// f_2.constructResponse();
239+
// float simi = features[features.size()-1]
240+
// .similarity(f_2);
241+
// std::cout << "\ndiff depth simi: " << simi << std::endl;
242+
// }
227243

228244
// if(features.size() > 1){
229245
// float simi = features[features.size()-2]
@@ -235,7 +251,7 @@ void simi_test(){
235251
}
236252
}
237253
int main(){
238-
254+
// API_test();
239255
simi_test();
240256
// google::protobuf::ShutdownProtobufLibrary();
241257
cout << "end" << endl;

0 commit comments

Comments
 (0)