Files
ios/Xuxucheck/XuXuCheck/opencv/Utils.cpp
T
admin d6aeede2bc 导入 XuXuCheck 工程(iOS 干化学尿液试纸分析 App)
从桌面工程复制而来,作为本仓库的 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。
2026-09-23 14:17:31 +08:00

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);
}