Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "jsk_recognition_utils/cv_utils.h"
00037
00038 namespace jsk_recognition_utils
00039 {
00040 cv::MatND computeHistogram(const cv::Mat& input_image, int bin_size,
00041 float min_value, float max_value,
00042 const cv::Mat& mask_image)
00043 {
00044 int channels[] = {0};
00045 cv::MatND hist;
00046 int hist_size[] = {bin_size};
00047 float range[] = {min_value, max_value};
00048 const float* ranges[] = {range};
00049 cv::calcHist(&input_image, 1, channels, mask_image,
00050 hist, 1, hist_size,
00051 ranges, true, false);
00052 return hist;
00053 }
00054
00055 std::vector<jsk_recognition_msgs::HistogramWithRangeBin>
00056 cvMatNDToHistogramWithRangeBinArray(const cv::MatND& cv_hist, float min_value, float max_value)
00057 {
00058 std::vector<jsk_recognition_msgs::HistogramWithRangeBin> bins(cv_hist.total());
00059 const float bin_width = (max_value - min_value) / cv_hist.total();
00060 for (size_t i = 0; i < cv_hist.total(); i++) {
00061 const float left = i * bin_width + min_value;
00062 const float right = (i + 1) * bin_width + min_value;
00063 jsk_recognition_msgs::HistogramWithRangeBin bin;
00064 bin.min_value = left;
00065 bin.max_value = right;
00066 bin.count = cv_hist.at<float>(0, i);
00067 bins[i] = bin;
00068 }
00069 return bins;
00070 }
00071
00072 bool compareHistogramWithRangeBin(const jsk_recognition_msgs::HistogramWithRangeBin& left,
00073 const jsk_recognition_msgs::HistogramWithRangeBin& right)
00074 {
00075 return left.count > right.count;
00076 }
00077
00078 void sortHistogramWithRangeBinArray(std::vector<jsk_recognition_msgs::HistogramWithRangeBin>& bins)
00079 {
00080 std::sort(bins.begin(), bins.end(), compareHistogramWithRangeBin);
00081 }
00082
00083 std::vector<jsk_recognition_msgs::HistogramWithRangeBin>
00084 topNHistogramWithRangeBins(const std::vector<jsk_recognition_msgs::HistogramWithRangeBin>& bins,
00085 double top_n_rate)
00086 {
00087 int sum = 0;
00088 for (size_t i = 0; i < bins.size(); i++) {
00089 sum += bins[i].count;
00090 }
00091 const int target_sum = sum * top_n_rate;
00092 std::vector<jsk_recognition_msgs::HistogramWithRangeBin> top_n_bins;
00093 top_n_bins.reserve(bins.size());
00094
00095 int current_sum = 0;
00096 for (size_t i = 0; i < bins.size(); i++) {
00097 jsk_recognition_msgs::HistogramWithRangeBin bin = bins[i];
00098 if (current_sum >= target_sum) {
00099 return top_n_bins;
00100 }
00101 top_n_bins.push_back(bin);
00102 current_sum += bins[i].count;
00103 }
00104 return top_n_bins;
00105 }
00106
00107 void
00108 drawHistogramWithRangeBin(cv::Mat& image,
00109 const jsk_recognition_msgs::HistogramWithRangeBin& bin,
00110 float min_width_value,
00111 float max_width_value,
00112 float max_height_value,
00113 cv::Scalar color)
00114 {
00115 if (max_height_value == 0.0) {
00116 return;
00117 }
00118 const int height = image.rows;
00119 const int width = image.cols;
00120 const int left = (bin.min_value - min_width_value) / (max_width_value - min_width_value) * width;
00121 const int right = (bin.max_value - min_width_value) / (max_width_value - min_width_value) * width;
00122 const int top = bin.count / max_height_value * height;
00123 if (bin.count == 0 || top == 0 || left == right || left < 0 || right >= width || top > height) {
00124 return;
00125 }
00126
00127 cv::rectangle(image, cv::Point(left, height), cv::Point(right, height - top),
00128 color, CV_FILLED);
00129 }
00130 }