2
A
回答
1
我不知道OpenCV,但我懷疑它已準備好使用此功能。然而,天真的實現可能是這樣的:
double m = cv::mean(mat);
Mat temp = mat;
... set all elements in temp to 0, where abs(temp[i][j] - m) > tolerance
... and count those elements in count
int N = mat.total(); // total number of elements
m = cv::sum(temp)/(N-count)
編輯:其實這不是什麼問題被要求。但是,如果可以假設值的高斯分佈,則可以基於標準偏差(必須計算)來估計值tolerance
以排除數據的上限/下限10%。
0
不,沒有OpenCV功能來做到這一點。但是,你可以實現你自己的。
最棘手的部分是計算與您的百分比相對應的值。這可以很容易地實現計算圖像的累積直方圖。
但是,要使該方法一般,您無法知道矩陣中的哪些值,因此您需要依賴maps
。
請注意,如果您僅在CV_8U
圖片上工作,則可以優化知道最多隻能有256個不同的值。要實現這一點,您可以提示here。
所以這是一個可能的實現,它可以在最多4個通道(如cv::mean
)的Mat
上工作,並且不需要先驗知道可能數量的不同值。您可以查看評論/ decommenting在例如矩陣intialization部分,它正確地執行:
#include <opencv2/opencv.hpp>
#include <vector>
#include <numeric>
#include <map>
#include <iostream>
using namespace cv;
using namespace std;
double robustMeanC1(const Mat1d& src, Vec2d bounds)
{
// Compute histogram (with no predefined range)
map<double, int> hist;
for (int r = 0; r < src.rows; ++r)
{
for (int c = 0; c < src.cols; ++c)
{
double key = src(r,c);
if (hist.count(key) == 0) {
hist.insert(make_pair(key, 1));
}
else {
hist[key]++;
}
}
}
// Get vectors from map
vector<double> vals;
vector<int> sums;
vals.reserve(hist.size());
sums.reserve(hist.size());
for (auto kv : hist)
{
vals.push_back(kv.first);
sums.push_back(kv.second);
}
// Compute cumulative histogram
vector<int> cumhist(sums);
for (int i=1; i<sums.size(); ++i)
{
cumhist[i] = cumhist[i - 1] + sums[i];
}
// Compute bounds
int total = src.rows * src.cols;
double low_bound = (total * bounds[0])/100.0;
double upp_bound = (total * bounds[1])/100.0;
int low_index = distance(cumhist.begin(), upper_bound(cumhist.begin(), cumhist.end(), low_bound));
int upp_index = distance(cumhist.begin(), upper_bound(cumhist.begin(), cumhist.end(), upp_bound));
if (low_index == upp_index) {upp_index++;}
// Compute mean
double mean = 0.0;
int count = 0;
for (int i = low_index; i < upp_index; ++i)
{
mean += vals[i] * sums[i];
count += sums[i];
}
mean /= count;
return mean;
}
Scalar robustMean(const Mat& src, Vec2d bounds)
{
Mat m;
src.convertTo(m, CV_64F);
Scalar res(0.0, 0.0, 0.0, 0.0);
if (m.channels() == 1)
{
res[0] = robustMeanC1(m, bounds);
}
else
{
vector<Mat1d> planes;
split(m, planes);
if (planes.size() > 4)
{
// Error, at most 4 channels
return Scalar(0,0,0,0);
}
for (int i = 0; i < planes.size(); ++i)
{
res[i] = robustMeanC1(planes[i], bounds);
}
}
return res;
}
int main()
{
Mat1d m(10,10, 5.f);
m(Range(0,1), Range::all()) = 2.0;
//m(Range(1, 2), Range::all()) = 80.0;
//randu(m, Scalar(0), Scalar(1));
//Mat3b m = imread("path_to_image");
Scalar rs = robustMean(m, Vec2d(10, 90));
Scalar s = mean(m);
cout << "Robust Mean: " << rs << endl;
cout << " Mean: " << s << endl;
return 0;
}
0
我就簡單的Mat
元素進行排序,並採取截斷矢量的平均
#include <algorithm>
#include <vector>
// c in [0,1] the portion of middvalues added to the mean
template<class _T> _T avg(std::vector<_T> & vec, double c)
{
if (c < 0.0)
c = 0.0;
else if (c > 1.0)
c = 1.0;
const size_t len = (size_t)(c * (double)vec.size());
if (len == 0)
return 0.0;
std::vector<_T>::iterator beg = vec.begin();
std::vector<_T>::iterator end = vec.end();
if (len < vec.size())
{
beg += (vec.size() - len)/2;
end = beg + len;
std::nth_element(vec.begin(), beg, vec.end());
std::nth_element(beg, end, vec.end());
}
double sum = 0.0, d = 0.0;
for (std::vector<_T>::iterator it = beg; it!=end; ++it, d+=1.0)
sum += *it;
return sum/d;
}
// fill the vector and compute for each channel separately.
這裏的尾巴和頭爲簡單起見,相同的部分。
相關問題
- 1. 查找平均值
- 2. 查找平均值
- 3. Python:查找平均值
- 4. SPARQL查找平均值?
- 5. 查找前n平均值
- 6. 查找數組中值的平均值
- 7. 查找平均SQL
- 8. Python-查找平均
- 9. 找到平均值(平均)在C++
- 10. 查找最小值,最大值,平均值,賠率和平均值。 Java
- 11. 如何找到無極分佈數的平均值?
- 12. 使用awk查找列的平均值
- 13. 如何在Access中查找平均值?
- 14. 查找列表的「居中平均值」
- 15. 查找矩陣的平均值
- 16. 查找非零元素的平均值
- 17. 如何查找最大平均值
- 18. SQL查找日期間的平均值
- 19. 查找VBA中列的平均值
- 20. 查找數字的平均值
- 21. 查找列表的平均值
- 22. 查找每組中的平均值
- 23. 熊貓查找多層次平均值
- 24. 查找學生的平均值
- 25. 在Python中查找平均值
- 26. 查找分數的平均值
- 27. 查找圖像Java的平均值
- 28. 查找TimeSpans收集的平均值
- 29. 查找matlab中的平均值
- 30. 查找密集矩陣的平均值
cv :: mean也認爲是零值。所以平均值會很低。 – Bschs
@Bschs這就是爲什麼最後一行糾正了規範化 – user463035818
@ tobi303這不適用於一般矩陣,其中值可以是例如小於0.但是,這種方法適用於圖像,因爲你有'容差「,這是不能修復的,但對每張圖像都要重新計算。所以這不能回答這個問題,因爲你錯過了如何計算閾值。剩下的就好了,Bschs是錯誤的:D – Miki