-
Notifications
You must be signed in to change notification settings - Fork 1
/
opencv-2.4.10.1_patch.diff
1959 lines (1610 loc) · 67 KB
/
opencv-2.4.10.1_patch.diff
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
diff -ur opencv-2.4.4/modules/gpu/include/opencv2/gpu/gpu.hpp opencv/modules/gpu/include/opencv2/gpu/gpu.hpp
--- opencv-2.4.4/modules/gpu/include/opencv2/gpu/gpu.hpp 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/gpu/include/opencv2/gpu/gpu.hpp 2015-07-20 14:43:20.773425700 +0100
@@ -1243,13 +1243,15 @@
{
enum { DEFAULT_WIN_SIGMA = -1 };
enum { DEFAULT_NLEVELS = 64 };
- enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL };
+ enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL, DESCR_FORMAT_MATRIX_ONLY };
+ enum { NORM_L2Hys=0, NORM_L1Sqrt=1 };
HOGDescriptor(Size win_size=Size(64, 128), Size block_size=Size(16, 16),
Size block_stride=Size(8, 8), Size cell_size=Size(8, 8),
int nbins=9, double win_sigma=DEFAULT_WIN_SIGMA,
double threshold_L2hys=0.2, bool gamma_correction=true,
- int nlevels=DEFAULT_NLEVELS);
+ int nlevels=DEFAULT_NLEVELS, int histogram_norm_type=NORM_L2Hys,
+ bool hist_bins_range_is_360deg = false);
size_t getDescriptorSize() const;
size_t getBlockHistogramSize() const;
@@ -1270,16 +1272,30 @@
int group_threshold=2);
void computeConfidence(const GpuMat& img, vector<Point>& hits, double hit_threshold,
- Size win_stride, Size padding, vector<Point>& locations, vector<double>& confidences);
+ Size win_stride, Size padding, vector<float>& weights);
void computeConfidenceMultiScale(const GpuMat& img, vector<Rect>& found_locations,
double hit_threshold, Size win_stride, Size padding,
- vector<HOGConfidence> &conf_out, int group_threshold);
+ vector<float>& weights, int group_threshold=2,double scale0=1.05);
+
+ //CB added computeConfidenceFromCells()
+ void computeConfidenceFromCells(const GpuMat& hist_cells, vector<Point>& hits,
+ double hit_threshold, Size win_stride, Size padding,
+ int rows, int cols, vector<float>& weights);
void getDescriptors(const GpuMat& img, Size win_stride,
GpuMat& descriptors,
int descr_format=DESCR_FORMAT_COL_BY_COL);
+ //CB added extraction of descriptors from cells
+ void getDescriptorsFromCells(const GpuMat& cell_hists, Size win_stride,
+ Size img_size, GpuMat& descriptors,
+ int descr_format=DESCR_FORMAT_COL_BY_COL);
+
+ //CB added method for re-setting constants in gpu constant memory when used with
+ //detectors for different objects
+ void reUploadConstants(void);
+
Size win_size;
Size block_size;
Size block_stride;
@@ -1289,6 +1305,9 @@
double threshold_L2hys;
bool gamma_correction;
int nlevels;
+
+ int histogram_norm_type; //normalisation method, either L2Hys or L1Sqrt
+ bool hist_bin_range_is_360deg; //use 180 or 360deg for bin range
protected:
void computeBlockHistograms(const GpuMat& img);
diff -ur opencv-2.4.4/modules/gpu/src/cuda/hog.cu opencv/modules/gpu/src/cuda/hog.cu
--- opencv-2.4.4/modules/gpu/src/cuda/hog.cu 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/gpu/src/cuda/hog.cu 2015-07-20 14:43:20.777429700 +0100
@@ -66,6 +66,7 @@
__constant__ int cblock_hist_size_2up;
__constant__ int cdescr_size;
__constant__ int cdescr_width;
+ __constant__ float cangle_bin_bias_value;
/* Returns the nearest upper power of two, works only for
@@ -88,7 +89,7 @@
void set_up_constants(int nbins, int block_stride_x, int block_stride_y,
- int nblocks_win_x, int nblocks_win_y)
+ int nblocks_win_x, int nblocks_win_y, bool hist_bin_range_is_360deg)
{
cudaSafeCall( cudaMemcpyToSymbol(cnbins, &nbins, sizeof(nbins)) );
cudaSafeCall( cudaMemcpyToSymbol(cblock_stride_x, &block_stride_x, sizeof(block_stride_x)) );
@@ -107,6 +108,9 @@
int descr_size = descr_width * nblocks_win_y;
cudaSafeCall( cudaMemcpyToSymbol(cdescr_size, &descr_size, sizeof(descr_size)) );
+
+ float angle_bias_value = hist_bin_range_is_360deg? 0.0f : CV_PI_F;
+ cudaSafeCall( cudaMemcpyToSymbol(cangle_bin_bias_value, &angle_bias_value, sizeof(angle_bias_value)) );
}
@@ -189,6 +193,10 @@
int tid = (cell_y * CELLS_PER_BLOCK_Y + cell_x) * 16 + cell_thread_x;
if (tid < cblock_hist_size)
block_hist[tid] = final_hist[block_x * cblock_hist_size + tid];
+ int n_extra_block_bins = max(0, cblock_hist_size - blockDim.x*blockDim.y);
+ if (tid< n_extra_block_bins ) //handle blocks >64 in length. this is kind of inefficient, dont care
+ block_hist[blockDim.x*blockDim.y +tid] = final_hist[block_x * cblock_hist_size +blockDim.x*blockDim.y+ tid];
+
}
@@ -222,6 +230,82 @@
cudaSafeCall( cudaDeviceSynchronize() );
}
+//CB added compute_block_hists_from_cells kernel
+ template <int nblocks> // Number of histogram blocks processed by single GPU thread block
+ __global__ void compute_block_hists_from_cells_kernel(const int img_block_width, const int img_block_height,
+ const PtrStepf cell_hists, float* block_hists)
+ {
+ //PtrStepf in header may have to change
+ const int cell_x = threadIdx.x;
+ const int cell_y = threadIdx.y;
+ const int cell_bin = threadIdx.z;
+
+ //check if within grid
+ if (blockIdx.x >= img_block_width||
+ blockIdx.y >= img_block_height)
+ return;
+ //check if within histogram
+ if (cell_x >= CELLS_PER_BLOCK_X || cell_y >= CELLS_PER_BLOCK_Y || cell_bin >= cnbins)
+ return;
+
+ //block_hists is a (img_block_width * img_block_height * cnbins(36)) vector,
+ //row-major (ie y*width +x *xsize + nbin)
+ //get base of current block: buffer offset * 36
+ float* block_hist = block_hists + (blockIdx.y * img_block_width + blockIdx.x ) * cblock_hist_size;
+ //get histogram bin [0-35] ->celly*16 + cellx * 8 + cell_bin
+ int tid = (cell_y * CELLS_PER_BLOCK_Y + cell_x) * cnbins+ cell_bin;
+
+ if (tid < cblock_hist_size) // tid < 36
+ {
+ //index into orig cell array using blockX and blockY
+
+ /*size of 1 cell - assume 16bit passed in * num of cells in a row (=blocks in row + 1)*/
+ const int offset_y = (blockIdx.y + cell_y) * cnbins * 1 * (img_block_width+1);
+ //constant will be 1 or 2 or 4 all the time depending on relative sizes
+ const int offset_x = (blockIdx.x + cell_x) * cnbins * 1;
+
+ block_hist[tid] = cell_hists.data[offset_y + offset_x + cell_bin];//original cell hist
+ //TODO use shared mem here instead: could probably write into a cblock_hist_size-long thing
+ //and then update external memory
+ //TODO check state of coalesced writes etc
+ //eg
+ // __shared__ float smem[cblock_hist_size];
+ //smem[tid] = calculation;
+ //__syncthreads();
+ //block_hist[tid] = smem[tid];
+
+ }
+ }
+
+ //CB added compute_block_hists_from_cell() wrapper
+ void compute_block_hists_from_cell(int nbins, int block_stride_x, int block_stride_y,
+ int height, int width, const PtrStepSzf& cell_hists, float* block_hists)
+ {
+ const int nblocks = 1;
+
+ int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) /
+ block_stride_x;
+ int img_block_height = (height - CELLS_PER_BLOCK_Y * CELL_HEIGHT + block_stride_y) /
+ block_stride_y;
+ //May need to include the -1 here as we strip LRUD borders from frame thus ncells and nblocks reduced by 1
+
+ dim3 grid(divUp(img_block_width, nblocks), img_block_height);
+ // this gives us grid( (imwidth/blocksize), imheight/blocksize, 1)
+ //set thread as threads(2,2,9)
+ dim3 threads(CELLS_PER_BLOCK_Y, CELLS_PER_BLOCK_X, nbins);
+ //dunno what this does so commenting out for now
+ //cudaSafeCall(cudaFuncSetCacheConfig(compute_block_hists_from_cells_kernel<nblocks>,
+ // cudaFuncCachePreferL1));
+
+ int hists_size = (nbins * CELLS_PER_BLOCK_X * CELLS_PER_BLOCK_Y * 12 * nblocks) * sizeof(float);
+ int final_hists_size = (nbins * CELLS_PER_BLOCK_X * CELLS_PER_BLOCK_Y * nblocks) * sizeof(float);
+ int smem = hists_size + final_hists_size;
+ compute_block_hists_from_cells_kernel<nblocks><<<grid, threads, smem>>>(
+ img_block_width, img_block_height, cell_hists, block_hists);
+ cudaSafeCall( cudaGetLastError() );
+ cudaSafeCall( cudaDeviceSynchronize() );
+ }
+
//-------------------------------------------------------------
// Normalization of histograms via L2Hys_norm
@@ -291,9 +375,41 @@
hist[0] = elem * scale;
}
+ //uses Dalal's L1-sqrt norm instead of L2-Hys. Possibly change the epsilon value
+ template <int nthreads, // Number of threads which process one block historgam
+ int nblocks> // Number of block hisograms processed by one GPU thread block
+ __global__ void normalize_hists_kernel_l1sqrt(
+ const int block_hist_size, const int img_block_width, float* block_hists, float threshold)
+ {
+ if (blockIdx.x * blockDim.z + threadIdx.z >= img_block_width)
+ return;
+
+ float* hist = block_hists + (blockIdx.y * img_block_width +
+ blockIdx.x * blockDim.z + threadIdx.z) *
+ block_hist_size + threadIdx.x;
+
+ __shared__ float sh_squares[nthreads * nblocks];
+ float* squares = sh_squares + threadIdx.z * nthreads;
+
+ float elem = 0.f;
+ if (threadIdx.x < block_hist_size)
+ elem = hist[0];
+ //14/8/13 changed to actually do a L1-sqrt norm instead of L2-sqrt
+ float sum = reduce_smem<nthreads>(squares, elem);
+
+ //bit of a question over epsilon-value for this. looks like fpga-version uses 0.5, matlab version uses 1. opencv usually uses 0.1*block_hist_size
+ //float scale = 1.0f / (::sqrtf(sum) + 0.1f * block_hist_size);
+ //float scale = 1.0f / (::sqrtf(sum) + 1.0f/*0.5f*/);
+ float scale = 1.0f / (sum + 1.0f/*0.5f*/);
+
+ if (threadIdx.x < block_hist_size)
+ hist[0] = ::sqrtf(elem * scale);
+ }
+
void normalize_hists(int nbins, int block_stride_x, int block_stride_y,
- int height, int width, float* block_hists, float threshold)
+ int height, int width, float* block_hists, float threshold,
+ int norm_method, const int l1sqrt_norm_method)
{
const int nblocks = 1;
@@ -305,19 +421,34 @@
int img_block_height = (height - CELLS_PER_BLOCK_Y * CELL_HEIGHT + block_stride_y) / block_stride_y;
dim3 grid(divUp(img_block_width, nblocks), img_block_height);
- if (nthreads == 32)
- normalize_hists_kernel_many_blocks<32, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
- else if (nthreads == 64)
- normalize_hists_kernel_many_blocks<64, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
- else if (nthreads == 128)
- normalize_hists_kernel_many_blocks<64, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
- else if (nthreads == 256)
- normalize_hists_kernel_many_blocks<256, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
- else if (nthreads == 512)
- normalize_hists_kernel_many_blocks<512, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
- else
- cv::gpu::error("normalize_hists: histogram's size is too big, try to decrease number of bins", __FILE__, __LINE__, "normalize_hists");
-
+ if (norm_method == l1sqrt_norm_method) { //cant really see a smarter way to do this other than pass in the enum for comparison here
+ if (nthreads == 32)
+ normalize_hists_kernel_l1sqrt<32, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 64)
+ normalize_hists_kernel_l1sqrt<64, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 128)
+ normalize_hists_kernel_l1sqrt<128, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 256)
+ normalize_hists_kernel_l1sqrt<256, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 512)
+ normalize_hists_kernel_l1sqrt<512, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else
+ cv::gpu::error("normalize_hists: histogram's size is too big, try to decrease number of bins", __FILE__, __LINE__, "normalize_hists");
+ }
+ else {
+ if (nthreads == 32)
+ normalize_hists_kernel_many_blocks<32, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 64)
+ normalize_hists_kernel_many_blocks<64, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 128)
+ normalize_hists_kernel_many_blocks<128, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 256)
+ normalize_hists_kernel_many_blocks<256, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else if (nthreads == 512)
+ normalize_hists_kernel_many_blocks<512, nblocks><<<grid, threads>>>(block_hist_size, img_block_width, block_hists, threshold);
+ else
+ cv::gpu::error("normalize_hists: histogram's size is too big, try to decrease number of bins", __FILE__, __LINE__, "normalize_hists");
+ }
cudaSafeCall( cudaGetLastError() );
cudaSafeCall( cudaDeviceSynchronize() );
@@ -386,6 +517,7 @@
compute_confidence_hists_kernel_many_blocks<nthreads, nblocks><<<grid, threads>>>(
img_win_width, img_block_width, win_block_stride_x, win_block_stride_y,
block_hists, coefs, free_coef, threshold, confidences);
+ cudaSafeCall( cudaGetLastError() );
cudaSafeCall(cudaThreadSynchronize());
}
@@ -641,7 +773,8 @@
mag0 = ::sqrtf(mag0);
- float ang = (::atan2f(best_dy, best_dx) + CV_PI_F) * angle_scale - 0.5f;
+ //float ang = (::atan2f(best_dy, best_dx) + CV_PI_F) * angle_scale - 0.5f; //change to match cpu version
+ float ang = (::atan2f(best_dy, best_dx) + cangle_bin_bias_value) * angle_scale - 0.5f;
int hidx = (int)::floorf(ang);
ang -= hidx;
hidx = (hidx + cnbins) % cnbins;
@@ -714,7 +847,8 @@
}
float mag = ::sqrtf(dx * dx + dy * dy);
- float ang = (::atan2f(dy, dx) + CV_PI_F) * angle_scale - 0.5f;
+ //float ang = (::atan2f(dy, dx) + CV_PI_F) * angle_scale - 0.5f; //change to match cpu version
+ float ang = (::atan2f(dy, dx) + cangle_bin_bias_value) * angle_scale - 0.5f;
int hidx = (int)::floorf(ang);
ang -= hidx;
hidx = (hidx + cnbins) % cnbins;
diff -ur opencv-2.4.4/modules/gpu/src/hog.cpp opencv/modules/gpu/src/hog.cpp
--- opencv-2.4.4/modules/gpu/src/hog.cpp 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/gpu/src/hog.cpp 2015-07-20 14:43:20.780469300 +0100
@@ -41,10 +41,11 @@
//M*/
#include "precomp.hpp"
+#include <stdio.h>
#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
-cv::gpu::HOGDescriptor::HOGDescriptor(Size, Size, Size, Size, int, double, double, bool, int) { throw_nogpu(); }
+cv::gpu::HOGDescriptor::HOGDescriptor(Size, Size, Size, Size, int, double, double, bool, int, int, bool) { throw_nogpu(); }
size_t cv::gpu::HOGDescriptor::getDescriptorSize() const { throw_nogpu(); return 0; }
size_t cv::gpu::HOGDescriptor::getBlockHistogramSize() const { throw_nogpu(); return 0; }
double cv::gpu::HOGDescriptor::getWinSigma() const { throw_nogpu(); return 0; }
@@ -54,11 +54,14 @@
void cv::gpu::HOGDescriptor::detectMultiScale(const GpuMat&, vector<Rect>&, double, Size, Size, double, int) { throw_nogpu(); }
void cv::gpu::HOGDescriptor::computeBlockHistograms(const GpuMat&) { throw_nogpu(); }
void cv::gpu::HOGDescriptor::getDescriptors(const GpuMat&, Size, GpuMat&, int) { throw_nogpu(); }
+void cv::gpu::HOGDescriptor::getDescriptorsFromCells(const GpuMat&, Size, Size, GpuMat&, int) { throw_nogpu(); }
std::vector<float> cv::gpu::HOGDescriptor::getDefaultPeopleDetector() { throw_nogpu(); return std::vector<float>(); }
std::vector<float> cv::gpu::HOGDescriptor::getPeopleDetector48x96() { throw_nogpu(); return std::vector<float>(); }
std::vector<float> cv::gpu::HOGDescriptor::getPeopleDetector64x128() { throw_nogpu(); return std::vector<float>(); }
-void cv::gpu::HOGDescriptor::computeConfidence(const GpuMat&, vector<Point>&, double, Size, Size, vector<Point>&, vector<double>&) { throw_nogpu(); }
-void cv::gpu::HOGDescriptor::computeConfidenceMultiScale(const GpuMat&, vector<Rect>&, double, Size, Size, vector<HOGConfidence>&, int) { throw_nogpu(); }
+void cv::gpu::HOGDescriptor::computeConfidence(const GpuMat&, vector<Point>&, double, Size, Size, vector<float>&) { throw_nogpu(); }
+void cv::gpu::HOGDescriptor::computeConfidenceMultiScale(const GpuMat&, vector<Rect>&, double, Size, Size, vector<float>&, int, double) { throw_nogpu(); }
+void cv::gpu::HOGDescriptor::computeConfidenceFromCells(const GpuMat&, vector<Point>&, double, Size, Size, int, int, vector<float>& ) { throw_nogpu(); }
+void cv::gpu::HOGDescriptor::reUploadConstants(void) { throw_nogpu(); }
#else
@@ -67,14 +70,20 @@
namespace hog
{
void set_up_constants(int nbins, int block_stride_x, int block_stride_y,
- int nblocks_win_x, int nblocks_win_y);
+ int nblocks_win_x, int nblocks_win_y, bool hist_bin_range_is_360deg);
- void compute_hists(int nbins, int block_stride_x, int blovck_stride_y,
+ void compute_hists(int nbins, int block_stride_x, int block_stride_y,
int height, int width, const cv::gpu::PtrStepSzf& grad,
const cv::gpu::PtrStepSzb& qangle, float sigma, float* block_hists);
+
+ void compute_block_hists_from_cell(int nbins, int block_stride_x, int block_stride_y,
+ int height, int width, const PtrStepSzf& cell_hists,
+ float* block_hists);
void normalize_hists(int nbins, int block_stride_x, int block_stride_y,
- int height, int width, float* block_hists, float threshold);
+ int height, int width, float* block_hists, float threshold,
+ int norm_method=cv::gpu::HOGDescriptor::NORM_L2Hys,
+ const int l1sqrt_norm_method = cv::gpu::HOGDescriptor::NORM_L2Hys);
void classify_hists(int win_height, int win_width, int block_stride_y,
int block_stride_x, int win_stride_y, int win_stride_x, int height,
@@ -104,8 +113,37 @@
using namespace ::cv::gpu::device;
+//cb debug - dump a matrix fo type matType( usually CV-32FC1) to file filename and/or console
+
+ inline void dumpCellHistMat(const cv::Mat _mat, int matType, const char* filename, bool dumpToConsole){
+ FILE* fh;
+ if (_mat.type() !=CV_32FC1)
+ printf("Block histogram type is wrong. Specified type is %d and matrix type is %d, isContinuous? %s\n",
+ matType, _mat.type(), _mat.isContinuous()? "true" : "false");
+ if (filename != NULL){
+ if (!(fh= fopen(filename,"w")))
+ printf("Failed opening histsdump file %s\n",filename);
+ }
+ if (fh ||dumpToConsole)
+ {
+ for (int kk=0;kk < _mat.rows; ++kk){
+ for (int jj=0;jj < _mat.cols; ++jj){
+ if (fh) fprintf(fh, "%f\n",_mat.ptr<float>(kk)[jj]);
+ if (dumpToConsole) printf("%f ",_mat.ptr<float>(kk)[jj]);
+ }
+ if (dumpToConsole) printf("\n");
+ }
+ if (fh)
+ fclose(fh);
+ }
+ }
+
+
+
cv::gpu::HOGDescriptor::HOGDescriptor(Size win_size_, Size block_size_, Size block_stride_, Size cell_size_,
- int nbins_, double win_sigma_, double threshold_L2hys_, bool gamma_correction_, int nlevels_)
+ int nbins_, double win_sigma_, double threshold_L2hys_,
+ bool gamma_correction_, int nlevels_, int histogram_norm_type_,
+ bool hist_bin_range_is_360deg_)
: win_size(win_size_),
block_size(block_size_),
block_stride(block_stride_),
@@ -114,7 +152,9 @@
win_sigma(win_sigma_),
threshold_L2hys(threshold_L2hys_),
gamma_correction(gamma_correction_),
- nlevels(nlevels_)
+ nlevels(nlevels_),
+ histogram_norm_type(histogram_norm_type_),
+ hist_bin_range_is_360deg(hist_bin_range_is_360deg_)
{
CV_Assert((win_size.width - block_size.width ) % block_stride.width == 0 &&
(win_size.height - block_size.height) % block_stride.height == 0);
@@ -129,7 +169,10 @@
CV_Assert(cells_per_block == Size(2, 2));
cv::Size blocks_per_win = numPartsWithin(win_size, block_size, block_stride);
- hog::set_up_constants(nbins, block_stride.width, block_stride.height, blocks_per_win.width, blocks_per_win.height);
+
+ //compute_gradients needs to add a value to the angle it gets from atan2.
+ //with unsigned bins (0-180deg) this is pi. with signed(0-360) bins this is zero.
+ hog::set_up_constants(nbins, block_stride.width, block_stride.height, blocks_per_win.width, blocks_per_win.height, hist_bin_range_is_360deg);
}
size_t cv::gpu::HOGDescriptor::getDescriptorSize() const
@@ -205,8 +248,9 @@
// qangle.create(img.size(), CV_8UC2);
_qangle = getBuffer(img.size(), CV_8UC2, qangle_buf);
+ int bin_scaling = hist_bin_range_is_360deg? 2 : 1;
- float angleScale = (float)(nbins / CV_PI);
+ float angleScale = (float)(nbins / ( bin_scaling * CV_PI));
switch (img.type())
{
case CV_8UC1:
@@ -233,7 +277,16 @@
grad, qangle, (float)getWinSigma(), block_hists.ptr<float>());
hog::normalize_hists(nbins, block_stride.width, block_stride.height, img.rows, img.cols,
- block_hists.ptr<float>(), (float)threshold_L2hys);
+ block_hists.ptr<float>(), (float)threshold_L2hys, histogram_norm_type,
+ NORM_L1Sqrt);
+ //testing code
+ static bool oneshot=false;
+ if(oneshot){
+ Mat testhists;
+ block_hists.download(testhists);
+ dumpCellHistMat(testhists,CV_32FC1,"gpuhistsdump_computeBlockHistograms.txt",false);
+ oneshot=false;
+ }
}
@@ -259,13 +312,16 @@
hog::extract_descrs_by_cols(win_size.height, win_size.width, block_stride.height, block_stride.width,
win_stride.height, win_stride.width, img.rows, img.cols, block_hists.ptr<float>(), descriptors);
break;
+ case DESCR_FORMAT_MATRIX_ONLY:
+ block_hists.copyTo(descriptors);
+ break;
default:
CV_Error(CV_StsBadArg, "Unknown descriptor format");
}
}
void cv::gpu::HOGDescriptor::computeConfidence(const GpuMat& img, vector<Point>& hits, double hit_threshold,
- Size win_stride, Size padding, vector<Point>& locations, vector<double>& confidences)
+ Size win_stride, Size padding, vector<float>& weights)
{
CV_Assert(padding == Size(0, 0));
@@ -292,70 +348,188 @@
float* vec = labels_host.ptr<float>();
// does not support roi for now..
- locations.clear();
- confidences.clear();
+ weights.clear();
for (int i = 0; i < wins_per_img.area(); i++)
{
int y = i / wins_per_img.width;
int x = i - wins_per_img.width * y;
- if (vec[i] >= hit_threshold)
- hits.push_back(Point(x * win_stride.width, y * win_stride.height));
-
- Point pt(win_stride.width * x, win_stride.height * y);
- locations.push_back(pt);
- confidences.push_back((double)vec[i]);
+ //note default behaviour of computeConfidence has been modified
+ //to dump all windows set hit_threshold to eg -99
+ if (vec[i] >= hit_threshold){
+ hits.push_back(Point(x * win_stride.width, y * win_stride.height));
+ weights.push_back((float)vec[i]);
+ }
}
}
+//CB added computeConfidenceFromCells
+void cv::gpu::HOGDescriptor::computeConfidenceFromCells(const GpuMat& cell_hists, vector<Point>& hits, double hit_threshold,
+ Size win_stride, Size padding, int rows, int cols, vector<float>& weights)
+{
+ CV_Assert(padding == Size(0, 0));
+ CV_Assert( cell_hists.type() == CV_32FC1);
+
+ hits.clear();
+ if (detector.empty())
+ return;
+
+ //contents of computeBlockHistograms(img);
+ size_t block_hist_size = getBlockHistogramSize();
+ Size blocks_per_img = numPartsWithin(Size(cols,rows), block_size, block_stride);
+
+ block_hists = getBuffer(1, static_cast<int>(block_hist_size * blocks_per_img.area()), CV_32F, block_hists_buf);
+ //cell mangling goes in here
+ hog::compute_block_hists_from_cell( nbins, block_stride.width, block_stride.height,
+ rows, cols, cell_hists, block_hists.ptr<float>());
+
+ //testing code
+ static bool oneshot=false;
+ if(oneshot){
+ Mat testhists;
+ block_hists.download(testhists);
+ dumpCellHistMat(testhists,CV_32FC1,"gpuhistsdump_FromCells.txt",false);
+ oneshot=false;
+ }
+
+ hog::normalize_hists(nbins, block_stride.width, block_stride.height, rows, cols,
+ block_hists.ptr<float>(), (float)threshold_L2hys, histogram_norm_type, NORM_L1Sqrt);
+
+ //testing code
+ static bool oneshot2=false;
+ if(oneshot2){
+ Mat testhists;
+ block_hists.download(testhists);
+ dumpCellHistMat(testhists,CV_32FC1,"normgpuhistsdump_FromCells.txt",false);
+ oneshot2=false;
+ }
+
+ //end contents of computeBlockHistograms
+
+ if (win_stride == Size())
+ win_stride = block_stride;
+ else
+ CV_Assert(win_stride.width % block_stride.width == 0 &&
+ win_stride.height % block_stride.height == 0);
+
+ Size wins_per_img = numPartsWithin(Size(cols,rows), win_size, win_stride);
+ labels.create(1, wins_per_img.area(), CV_32F);
+
+ hog::compute_confidence_hists(win_size.height, win_size.width, block_stride.height, block_stride.width,
+ win_stride.height, win_stride.width, rows, cols, block_hists.ptr<float>(),
+ detector.ptr<float>(), (float)free_coef, (float)hit_threshold, labels.ptr<float>());
+
+ labels.download(labels_host);
+ float* vec = labels_host.ptr<float>();
+
+ //testing code
+ static bool oneshot3=false;
+ if(oneshot3){
+ Mat testhists;
+ block_hists.download(testhists);
+ dumpCellHistMat(testhists,CV_32FC1,"gpuscores_FromCells.txt",false);
+ oneshot3=false;
+ }
+
+ // does not support roi for now..
+ weights.clear();
+ for (int i = 0; i < wins_per_img.area(); i++)
+ {
+ int y = i / wins_per_img.width;
+ int x = i - wins_per_img.width * y;
+
+ //to dump all windows, set hit_threshold really -ve
+ //note default behaviour of computeConfidence has been modified
+ if (vec[i] >= hit_threshold){
+ hits.push_back(Point(x * win_stride.width, y * win_stride.height));
+ weights.push_back(vec[i]);
+ }
+ }
+}
+
+//cb: used to re-upload cosntants when working with multiple detectors with different properties,
+//all of which share the same constant space on the gpu
+void cv::gpu::HOGDescriptor::reUploadConstants(){
+ cv::Size blocks_per_win = numPartsWithin(win_size, block_size, block_stride);
+ hog::set_up_constants(nbins, block_stride.width, block_stride.height, blocks_per_win.width, blocks_per_win.height, hist_bin_range_is_360deg);
+}
+
void cv::gpu::HOGDescriptor::computeConfidenceMultiScale(const GpuMat& img, vector<Rect>& found_locations,
- double hit_threshold, Size win_stride, Size padding,
- vector<HOGConfidence> &conf_out, int group_threshold)
+ double hit_threshold, Size win_stride, Size padding,
+ vector<float> &weights, int group_threshold, double scale0)
{
- vector<double> level_scale;
- double scale = 1.;
- int levels = 0;
+ CV_Assert(img.type() == CV_8UC1 || img.type() == CV_8UC4);
- for (levels = 0; levels < (int)conf_out.size(); levels++)
- {
- scale = conf_out[levels].scale;
- level_scale.push_back(scale);
- if (cvRound(img.cols/scale) < win_size.width || cvRound(img.rows/scale) < win_size.height)
+ //multiple instances of HOG fight with each other in terms of constants so we force updates of constants on the gpu here.
+ //from now on, use detectMultiScale for less fannying about/higher speed
+ reUploadConstants();
+ /*cv::Size blocks_per_win = numPartsWithin(win_size, block_size, block_stride);
+ hog::set_up_constants(nbins, block_stride.width, block_stride.height, blocks_per_win.width, blocks_per_win.height, hist_bin_range_is_360deg);*/
+ /////////////////////////////////////////////
+ vector<double> level_scale;
+ double scale = 1.;
+ int levels = 0;
+
+ for (levels = 0; levels < nlevels; levels++)
+ {
+ level_scale.push_back(scale);
+ if (cvRound(img.cols/scale) < win_size.width ||
+ cvRound(img.rows/scale) < win_size.height || scale0 <= 1)
break;
- }
+ scale *= scale0;
+ }
- levels = std::max(levels, 1);
- level_scale.resize(levels);
-
- std::vector<Rect> all_candidates;
- vector<Point> locations;
-
- for (size_t i = 0; i < level_scale.size(); i++)
- {
- scale = level_scale[i];
- Size sz(cvRound(img.cols / scale), cvRound(img.rows / scale));
- GpuMat smaller_img;
-
- if (sz == img.size())
- smaller_img = img;
- else
- {
- smaller_img.create(sz, img.type());
- switch (img.type())
- {
- case CV_8UC1: hog::resize_8UC1(img, smaller_img); break;
- case CV_8UC4: hog::resize_8UC4(img, smaller_img); break;
- }
- }
-
- computeConfidence(smaller_img, locations, hit_threshold, win_stride, padding, conf_out[i].locations, conf_out[i].confidences);
-
- Size scaled_win_size(cvRound(win_size.width * scale), cvRound(win_size.height * scale));
- for (size_t j = 0; j < locations.size(); j++)
- all_candidates.push_back(Rect(Point2d((CvPoint)locations[j]) * scale, scaled_win_size));
- }
-
- found_locations.assign(all_candidates.begin(), all_candidates.end());
- groupRectangles(found_locations, group_threshold, 0.2/*magic number copied from CPU version*/);
+ levels = std::max(levels, 1);
+ level_scale.resize(levels);
+
+ std::vector<Rect> all_candidates;
+ vector<Point> locations;
+ vector<int> weights_int;
+
+ for (size_t i = 0; i < level_scale.size(); i++)
+ {
+ scale = level_scale[i];
+ Size sz(cvRound(img.cols / scale), cvRound(img.rows / scale));
+ GpuMat smaller_img;
+ vector<float> level_weights;
+
+ if (sz == img.size())
+ smaller_img = img;
+ else
+ {
+ smaller_img.create(sz, img.type());
+ switch (img.type())
+ {
+ case CV_8UC1: hog::resize_8UC1(img, smaller_img); break;
+ case CV_8UC4: hog::resize_8UC4(img, smaller_img); break;
+ }
+ }
+
+ computeConfidence(smaller_img, locations, hit_threshold, win_stride, padding, level_weights);
+
+ Size scaled_win_size(cvRound(win_size.width * scale), cvRound(win_size.height * scale));
+ for (size_t j = 0; j < locations.size(); j++){
+ all_candidates.push_back(Rect(Point2d((CvPoint)locations[j]) * scale, scaled_win_size));
+ weights.push_back(level_weights[j]);
+ }
+
+ }
+
+ found_locations.assign(all_candidates.begin(), all_candidates.end());
+ //if VC++ bitches about next line put a transform() in here
+ //maybe make this ceil()
+ weights_int.assign(weights.begin(),weights.end());
+ /*bool use_meanshift = false;
+ if (use_meanshift){
+ //extract out locations and confidences from HOGConfidence
+ groupRectangles_meanshift(found_locations, weights, cand_scales, group_threshold, win_size);
+ score.clear();
+ score.assign(cand_scores.begin(),cand_scores.end());
+ }
+ else*/
+ //expanded to return weights as well
+ groupRectangles(found_locations, weights_int,group_threshold, 0.2/*magic number copied from CPU version*/);
+ if (group_threshold!=0)
+ weights.assign(weights_int.begin(),weights_int.end());
}
@@ -394,6 +568,58 @@
}
}
+void cv::gpu::HOGDescriptor::getDescriptorsFromCells(const GpuMat& cell_hists, Size win_stride, Size img_size, GpuMat& descriptors, int descr_format)
+{
+ CV_Assert( cell_hists.type() == CV_32FC1);
+
+ if (detector.empty())
+ return;
+ // contents of computeBlockHistograms(img);
+ size_t block_hist_size = getBlockHistogramSize();
+
+ Size blocks_per_img = numPartsWithin(img_size, block_size, block_stride);
+
+ // block_hists.create(1, block_hist_size * blocks_per_img.area(), CV_32F);
+ block_hists = getBuffer(1, static_cast<int>(block_hist_size * blocks_per_img.area()), CV_32F, block_hists_buf);
+ //cell mangling goes in here
+ hog::compute_block_hists_from_cell( nbins, block_stride.width, block_stride.height,
+ img_size.height, img_size.width, cell_hists, block_hists.ptr<float>());
+
+ //testing code
+ static bool oneshot2=false;
+ if(oneshot2){
+ Mat testhists;
+ block_hists.download(testhists);
+ dumpCellHistMat(testhists,CV_32FC1,"gpuhistsdump_getDescriptors.txt",false);
+ oneshot2=false;
+ }
+
+ hog::normalize_hists(nbins, block_stride.width, block_stride.height, img_size.height, img_size.width,
+ block_hists.ptr<float>(), (float)threshold_L2hys, histogram_norm_type, NORM_L1Sqrt);
+
+
+ Size blocks_per_win = numPartsWithin(win_size, block_size, block_stride);
+ Size wins_per_img = numPartsWithin(img_size, win_size, win_stride);
+
+ descriptors.create(wins_per_img.area(), static_cast<int>(blocks_per_win.area() * block_hist_size), CV_32F);
+
+ switch (descr_format)
+ {
+ case DESCR_FORMAT_ROW_BY_ROW:
+ hog::extract_descrs_by_rows(win_size.height, win_size.width, block_stride.height, block_stride.width,
+ win_stride.height, win_stride.width, img_size.height, img_size.width, block_hists.ptr<float>(), descriptors);
+ break;
+ case DESCR_FORMAT_COL_BY_COL:
+ hog::extract_descrs_by_cols(win_size.height, win_size.width, block_stride.height, block_stride.width,
+ win_stride.height, win_stride.width, img_size.height, img_size.width, block_hists.ptr<float>(), descriptors);
+ break;
+ case DESCR_FORMAT_MATRIX_ONLY:
+ block_hists.copyTo(descriptors);
+ break;
+ default:
+ CV_Error(CV_StsBadArg, "Unknown descriptor format");
+ }
+}
void cv::gpu::HOGDescriptor::detectMultiScale(const GpuMat& img, vector<Rect>& found_locations, double hit_threshold,
diff -ur opencv-2.4.4/modules/highgui/include/opencv2/highgui/highgui.hpp opencv/modules/highgui/include/opencv2/highgui/highgui.hpp
--- opencv-2.4.4/modules/highgui/include/opencv2/highgui/highgui.hpp 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/highgui/include/opencv2/highgui/highgui.hpp 2015-07-20 14:43:20.788478900 +0100
@@ -156,6 +156,9 @@
CV_EXPORTS int createButton( const string& bar_name, ButtonCallback on_change,
void* userdata=NULL, int type=CV_PUSH_BUTTON,
bool initial_button_state=0);
+//cb edit: -1 toggles, 0 or 1 clear or set. probably a good reason this wasnt exposed before...
+CV_EXPORTS int setButtonState( const string& button_name, int new_state=-1);
+
//-------------------------
diff -ur opencv-2.4.4/modules/highgui/include/opencv2/highgui/highgui_c.h opencv/modules/highgui/include/opencv2/highgui/highgui_c.h
--- opencv-2.4.4/modules/highgui/include/opencv2/highgui/highgui_c.h 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/highgui/include/opencv2/highgui/highgui_c.h 2015-07-20 14:43:20.790441400 +0100
@@ -84,6 +84,8 @@
typedef void (CV_CDECL *CvButtonCallback)(int state, void* userdata);
enum {CV_PUSH_BUTTON = 0, CV_CHECKBOX = 1, CV_RADIOBOX = 2};
CVAPI(int) cvCreateButton( const char* button_name CV_DEFAULT(NULL),CvButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL) , int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0));
+//cb edit: -1 toggles, 0 or 1 clear or set checkbox. probably a good reason this wasnt exposed before...
+CVAPI(int) cvSetButtonState( const char* button_name CV_DEFAULT(NULL), int new_state CV_DEFAULT(-1));
//----------------------
diff -ur opencv-2.4.4/modules/highgui/src/window.cpp opencv/modules/highgui/src/window.cpp
--- opencv-2.4.4/modules/highgui/src/window.cpp 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/highgui/src/window.cpp 2015-07-20 14:43:20.792441600 +0100
@@ -398,6 +398,12 @@
return cvCreateButton(button_name.c_str(), on_change, userdata, button_type , initial_button_state );
}
+//cb edit
+int cv::setButtonState(const string& button_name, int new_state)
+{
+ return cvSetButtonState(button_name.c_str(), new_state);
+}
+
#else
CvFont cv::fontQt(const string&, int, Scalar, int, int, int)
@@ -617,6 +623,12 @@
return -1;
}
+CV_IMPL int cvSetButtonState(const char*, int)
+{
+ CV_NO_GUI_ERROR("cvSetButtonState");
+ return -1;
+}
+
#endif
diff -ur opencv-2.4.4/modules/highgui/src/window_QT.cpp opencv/modules/highgui/src/window_QT.cpp
--- opencv-2.4.4/modules/highgui/src/window_QT.cpp 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/highgui/src/window_QT.cpp 2015-07-20 14:43:20.795443500 +0100
@@ -619,6 +619,24 @@
return 1;//dummy value
}
+//cb edit
+CV_IMPL int cvSetButtonState(const char* button_name, int new_state)
+{
+ if (!guiMainThread)
+ CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );
+
+ if (new_state < -1 || new_state > 1)
+ return 0;
+
+ QMetaObject::invokeMethod(guiMainThread,
+ "setButtonState",
+ Qt::AutoConnection,
+ Q_ARG(QString, QString(button_name)),
+ Q_ARG(int, new_state));
+
+ return 1;//dummy value
+}
+
CV_IMPL int cvGetTrackbarPos(const char* name_bar, const char* window_name)
{
@@ -1080,6 +1098,25 @@
b->addButton(button_name, (CvButtonCallback) on_change, userdata, button_type, initial_button_state);
}
+void GuiReceiver::setButtonState(QString button_name, int new_state)
+{
+ if (!global_control_panel)
+ return;
+
+ QPointer<CvButtonbar> b;
+
+ int nbars = global_control_panel->myLayout->count();
+ for (int i=0;i<nbars;i++){ //search for correct buttton over all bars
+ CvBar* thisbar = (CvBar*) global_control_panel->myLayout->itemAt(i);
+ if (thisbar->type == type_CvButtonbar){
+ b = (CvButtonbar*) thisbar;
+ //search b for a button with given name and attempt to set its state
+ if (b->setButtonState(button_name, new_state))
+ return; //returns true if found
+ }
+ }
+}
+
void GuiReceiver::addSlider2(QString bar_name, QString window_name, void* value, int count, void* on_change, void *userdata)
{
@@ -1373,6 +1410,27 @@
}
}
+//cb edit
+bool CvButtonbar::setButtonState(QString name_button, int new_state)
+{
+ int nItems =count(); //layout()->?
+ bool found = false;
+
+ for (int i=0; i<nItems;i++){
+ QWidget* temp = (QWidget*)itemAt(i)->widget();
+ //maybe check if checkbox?
+ if (temp->objectName() == name_button){
+ CvCheckBox* button = (CvCheckBox*) temp;
+ if (new_state == -1) //toggle
+ button->isChecked()? button->setChecked(0) : button->setChecked(1);
+ else //set
+ button->setChecked(new_state);
+ return true;
+ }
+ }
+ return found; //not found
+}
+
//////////////////////////////////////////////////////
// Buttons
diff -ur opencv-2.4.4/modules/highgui/src/window_QT.h opencv/modules/highgui/src/window_QT.h
--- opencv-2.4.4/modules/highgui/src/window_QT.h 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/highgui/src/window_QT.h 2015-07-20 14:43:20.797446100 +0100
@@ -145,6 +145,9 @@
void updateWindow(QString name);
double isOpenGl(QString name);
+ //cb extension
+ void setButtonState(QString button_name, int new_state);
+
private:
int nb_windows;
bool doesExternalQAppExist;
@@ -168,6 +171,8 @@
CvButtonbar(QWidget* arg, QString bar_name);
void addButton(QString button_name, CvButtonCallback call, void* userdata, int button_type, int initial_button_state);
+ //cb extension
+ bool setButtonState(QString button_name, int new_state);
private:
void setLabel();
diff -ur opencv-2.4.4/modules/objdetect/include/opencv2/objdetect/objdetect.hpp opencv/modules/objdetect/include/opencv2/objdetect/objdetect.hpp
--- opencv-2.4.4/modules/objdetect/include/opencv2/objdetect/objdetect.hpp 2013-03-01 15:44:17.000000000 +0000
+++ opencv/modules/objdetect/include/opencv2/objdetect/objdetect.hpp 2015-07-20 14:43:20.805463000 +0100
@@ -505,24 +505,25 @@
struct CV_EXPORTS_W HOGDescriptor
{
public:
- enum { L2Hys=0 };
+ enum { L2Hys=0, L1Sqrt=1 };
enum { DEFAULT_NLEVELS=64 };
CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
histogramNormType(HOGDescriptor::L2Hys), L2HysThreshold(0.2), gammaCorrection(true),
- nlevels(HOGDescriptor::DEFAULT_NLEVELS)
+ nlevels(HOGDescriptor::DEFAULT_NLEVELS), histBinsRangeIs360Deg(false)
{}
CV_WRAP HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,
Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,
int _histogramNormType=HOGDescriptor::L2Hys,
double _L2HysThreshold=0.2, bool _gammaCorrection=false,
- int _nlevels=HOGDescriptor::DEFAULT_NLEVELS)
+ int _nlevels=HOGDescriptor::DEFAULT_NLEVELS, bool _histBinsRangeIs360Deg = false)
: winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
- gammaCorrection(_gammaCorrection), nlevels(_nlevels)
+ gammaCorrection(_gammaCorrection), nlevels(_nlevels),
+ histBinsRangeIs360Deg(_histBinsRangeIs360Deg)
{}
CV_WRAP HOGDescriptor(const String& filename)
@@ -575,6 +576,16 @@
double hitThreshold=0, Size winStride=Size(),
Size padding=Size(), double scale=1.05,
double finalThreshold=2.0, bool useMeanshiftGrouping = false) const;
+ //with found weights output
+ CV_WRAP virtual void detectFromCells(const Mat& cellhists, CV_OUT vector<Point>& foundLocations,
+ vector<double>& weights, Size imsz, double hitThreshold=0,
+ Size winStride=Size(), Size padding=Size(),
+ const vector<Point>& searchLocations=vector<Point>()) const;
+ //without found weights output
+ CV_WRAP virtual void detectFromCells(const Mat& cellhists, CV_OUT vector<Point>& foundLocations,
+ Size imsz, double hitThreshold=0,
+ Size winStride=Size(), Size padding=Size(),
+ const vector<Point>& searchLocations=vector<Point>()) const;
CV_WRAP virtual void computeGradient(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& angleOfs,
Size paddingTL=Size(), Size paddingBR=Size()) const;
@@ -594,6 +605,7 @@
CV_PROP bool gammaCorrection;