d6aeede2bc
从桌面工程复制而来,作为本仓库的 Xuxucheck/ 子目录。 为控制仓库体积做了两处删减: - 移除 Frameworks/opencv2.xcframework 下的两个 visionOS 切片 (xros-arm64、xros-arm64-simulator,合计约 106 MB),并同步删掉该 xcframework 内 Info.plist 里对应的两条 AvailableLibraries 记录, 只保留 ios-arm64 与 ios-arm64_x86_64-simulator。 - 移除全部 .DS_Store 与 xcuserdata/。 已用 xcodebuild 从本目录完整编译验证:BUILD SUCCEEDED, ProcessXCFramework 以 --platform ios 成功选中框架,产物含 3699 个 cv:: 符号 (OpenCV 确实链入),嵌入 framework 3 个,与移除无用 pod 之后的状态一致。 仓库约 206 MB,其中 OpenCV 203 MB、其余源码与依赖约 3 MB。
156 lines
3.4 KiB
C++
156 lines
3.4 KiB
C++
/*
|
|
* Utils.cpp
|
|
*
|
|
* Created on: 2018-1-14
|
|
* Author: neo
|
|
*/
|
|
#include "Utils.h"
|
|
#define TV0 8
|
|
#define TV1 5
|
|
void Whitebalance(Mat src,Point wbPt)
|
|
{
|
|
Rect roi(wbPt.x-5,wbPt.y-5,10,10);
|
|
Mat wbMat(src,roi);
|
|
cv::Scalar avgRgb = mean(wbMat);
|
|
// double d1 = avgRgb.val[0] - avgRgb.val[2];
|
|
// double d2= avgRgb.val[1]-avgRgb.val[2];
|
|
// double d3 = abs(avgRgb.val[0] - avgRgb.val[1]);
|
|
//
|
|
// if (d1 >= TV0 && d2 >= TV0 && d3 <= TV1)
|
|
// {
|
|
// avgRgb = mean(src);
|
|
// }
|
|
|
|
double scale = (avgRgb.val[0] + avgRgb.val[1] + avgRgb.val[2]) / 3;
|
|
Mat r,g,b;
|
|
extractChannel(src, r, 0);
|
|
extractChannel(src, g, 1);
|
|
extractChannel(src, b, 2);
|
|
|
|
convertScaleAbs(r, r, scale / avgRgb.val[0], 0.0);
|
|
convertScaleAbs(g, g, scale / avgRgb.val[1], 0.0);
|
|
convertScaleAbs(b, b, scale / avgRgb.val[2], 0.0);
|
|
|
|
vector<Mat> mv;
|
|
mv.push_back(r);
|
|
mv.push_back(g);
|
|
mv.push_back(b);
|
|
merge(mv, src);
|
|
|
|
}
|
|
|
|
|
|
//Perfect reflection color correction
|
|
void WhitebalancePR(Mat src,Point wbPt)
|
|
{
|
|
|
|
// 通道分离
|
|
vector<cv::Mat> Channel;
|
|
cv::split(src, Channel);
|
|
|
|
// 定义参数
|
|
int row = src.rows;
|
|
int col = src.cols;
|
|
int RGBSum[766] = { 0 };
|
|
uchar maxR, maxG, maxB;
|
|
|
|
for (int i = 0; i < row; ++i)
|
|
{
|
|
uchar *b = Channel[0].ptr<uchar>(i);
|
|
uchar *g = Channel[1].ptr<uchar>(i);
|
|
uchar *r = Channel[2].ptr<uchar>(i);
|
|
for (int j = 0; j < col; ++j)
|
|
{
|
|
int sum = b[j] + g[j] + r[j];
|
|
RGBSum[sum]++;
|
|
maxB = max(maxB, b[j]);
|
|
maxG = max(maxG, g[j]);
|
|
maxR = max(maxR, r[j]);
|
|
}
|
|
}
|
|
|
|
int T = 0;
|
|
int num = 0;
|
|
int K = static_cast<int>(row * col * 0.1);
|
|
for (int i = 765; i >= 0; --i)
|
|
{
|
|
num += RGBSum[i];
|
|
if (num > K)
|
|
{
|
|
T = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
double Bm = 0.0, Gm = 0.0, Rm = 0.0;
|
|
int count = 0;
|
|
for (int i = 0; i < row; ++i)
|
|
{
|
|
uchar *b = Channel[0].ptr<uchar>(i);
|
|
uchar *g = Channel[1].ptr<uchar>(i);
|
|
uchar *r = Channel[2].ptr<uchar>(i);
|
|
for (int j = 0; j < col; ++j)
|
|
{
|
|
int sum = b[j] + g[j] + r[j];
|
|
if (sum > T)
|
|
{
|
|
Bm += b[j];
|
|
Gm += g[j];
|
|
Rm += r[j];
|
|
count++;
|
|
}
|
|
|
|
}
|
|
}
|
|
Bm /= count;
|
|
Gm /= count;
|
|
Rm /= count;
|
|
|
|
Channel[0] *= maxB / Bm;
|
|
Channel[1] *= maxG / Gm;
|
|
Channel[2] *= maxR / Rm;
|
|
|
|
cv::merge(Channel, src);
|
|
}
|
|
|
|
bool pred(const std::pair<int, int>& lhs,const std::pair<int, int>& rhs)
|
|
{
|
|
return lhs.second < rhs.second;
|
|
}
|
|
|
|
int GetHModal(Mat h)
|
|
{
|
|
uchar *pData=h.data;
|
|
int step=h.step;
|
|
//key:h,value:counter
|
|
map<int,int> mapVals;
|
|
map<int,int>::iterator it;
|
|
for (int y=0;y<h.rows;++y){
|
|
for(int x=0;x<h.cols;++x){
|
|
uchar val=pData[y*step+x];
|
|
it=mapVals.find(val);
|
|
if (it!=mapVals.end()){
|
|
mapVals[val]++;
|
|
}else{
|
|
mapVals.insert(make_pair(val,1));
|
|
}
|
|
}
|
|
}
|
|
it=std::max_element(mapVals.begin(),mapVals.end(),pred);
|
|
int maxHval=it->first;
|
|
int sum=0;
|
|
int pc=0;
|
|
for (it=mapVals.begin();it!=mapVals.end();++it){
|
|
int h=it->first;
|
|
int c=it->second;
|
|
if (h>=(maxHval-2)&&
|
|
h<=(maxHval+2)){
|
|
sum+=h*c;
|
|
pc+=c;
|
|
}
|
|
}
|
|
return (sum/pc);
|
|
}
|
|
|
|
|