Files
ios/Xuxucheck/XuXuCheck/opencv/OpencvWrapper.mm
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

182 lines
6.1 KiB
Plaintext

//
// OpencvWrapper.m
// XuXuCheck
//
// Created by henseycai on 2025/5/26.
//
// OpenCVWrapper.mm
#import <opencv2/opencv.hpp>
#import <opencv2/imgcodecs/ios.h>
#import <vector>
#import "ImageLocation.h"
#import "OpenCVWrapper.h"
@interface UIImage (OpenCVWrapper)
- (void)convertToMat: (cv::Mat *)pMat: (bool)alphaExists;
@end
@implementation UIImage (OpenCVWrapper)
- (void)convertToMat: (cv::Mat *)pMat: (bool)alphaExists {
if (self.imageOrientation == UIImageOrientationRight) {
UIImageToMat([UIImage imageWithCGImage:self.CGImage scale:1.0 orientation:UIImageOrientationUp], *pMat, alphaExists);
cv::rotate(*pMat, *pMat, cv::ROTATE_90_CLOCKWISE);
} else if (self.imageOrientation == UIImageOrientationLeft) {
UIImageToMat([UIImage imageWithCGImage:self.CGImage scale:1.0 orientation:UIImageOrientationUp], *pMat, alphaExists);
cv::rotate(*pMat, *pMat, cv::ROTATE_90_COUNTERCLOCKWISE);
} else {
UIImageToMat(self, *pMat, alphaExists);
if (self.imageOrientation == UIImageOrientationDown) {
cv::rotate(*pMat, *pMat, cv::ROTATE_180);
}
}
}
@end
@implementation OpenCVWrapper
ImageLocation imgLoc;
+ (UIImage *)gaussianBlur:(UIImage *)image: (int)blurAmount {
cv::Mat mat;
[image convertToMat:&mat :false];
cv::Mat blur;
mat.copyTo(blur);
cv::GaussianBlur(mat, blur, cv::Size(blurAmount, blurAmount), 0.0);
UIImage* blurImage = MatToUIImage(blur);
return blurImage;
}
+ (UIImage *)toGrayscale:(UIImage *)image {
cv::Mat mat;
[image convertToMat: &mat :false];
std::vector<cv::Point> positions;
cv::Scalar scPaperParams(0);
cv::Rect roi(0,0,mat.cols,mat.rows / 3);
cv:Scalar scalar(0);
Mat roiRotImage;
Mat srcImgMatBgra;
cvtColor(mat, srcImgMatBgra, COLOR_RGBA2BGRA); //rgba---->>rgb
Mat reImag = imgLoc.LocationProc(srcImgMatBgra, roi, true,scPaperParams,scalar, positions, roiRotImage);
cvtColor(reImag, reImag, COLOR_BGRA2RGBA);
// reImag.copyTo(retImgMat);
// roiRotImage.copyTo(roiRotImgMat);
UIImage *grayImg = MatToUIImage(reImag);
return grayImg;
// cv::Mat gray;
// if (mat.channels() > 1) {
// cv::cvtColor(mat, gray, cv::COLOR_RGB2GRAY);
// } else {
// mat.copyTo(gray);
// }
// UIImage *grayImg = MatToUIImage(gray);
// return grayImg;
}
int ITEM_SIZE = 16;
ImgResult* result = [ImgResult new];
+ (ImgResult *)analysisImage:(UIImage *)image {
cv::Mat mat;
[image convertToMat: &mat :false];
std::vector<cv::Point> positions;
cv::Scalar scPaperParams(0);
cv::Rect roi(0,0,mat.cols,mat.rows / 3);
cv:Scalar scalar(0);
Mat roiRotImage;
Mat srcImgMatBgra;
cvtColor(mat, srcImgMatBgra, COLOR_RGBA2BGRA); //rgba---->>rgb
Mat reImag = imgLoc.LocationProc(srcImgMatBgra, roi, true,scPaperParams,scalar, positions, roiRotImage);
cvtColor(reImag, reImag, COLOR_BGRA2RGBA);
// reImag.copyTo(retImgMat);
// roiRotImage.copyTo(roiRotImgMat);
result.srcImg = MatToUIImage(reImag);
// result.roiImg = MatToUIImage(roiRotImage);
result.paperWbValue[0] = [NSNumber numberWithDouble:scalar.val[0]];
result.paperWbValue[1] = [NSNumber numberWithDouble:scalar.val[1]] ;
result.paperWbValue[2] = [NSNumber numberWithDouble:scalar.val[2]] ;
result.paperWbValue[3] = [NSNumber numberWithDouble:scalar.val[3]] ;
// result.paperWbValue[0] = [NSNumber numberWithInt:imgLoc.GetPaperColor()];
// result.paperWbValue[1] = [NSNumber numberWithInt:imgLoc.GetPaperItems()] ;
// result.paperWbValue[2] = [NSNumber numberWithInt:imgLoc.GetPaperLocLength()] ;
// result.paperWbValue[3] = [NSNumber numberWithInt:scalar.val[3]] ;
result.paperTypeDesc[0] = @0.0;
result.paperTypeDesc[1] = @0.0;
result.paperTypeDesc[2] = @0.0;
result.paperTypeDesc[3] = @0.0;
if(scalar.val[3] == 0){
result.paperTypeDesc[0] = [NSNumber numberWithDouble:scPaperParams.val[0]];
result.paperTypeDesc[1] = [NSNumber numberWithDouble:scPaperParams.val[1]] ;
result.paperTypeDesc[2] = [NSNumber numberWithDouble:scPaperParams.val[2]] ;
result.paperTypeDesc[3] = [NSNumber numberWithDouble:scPaperParams.val[3]] ;
result.paperTypeDesc[0] = [NSNumber numberWithInt:imgLoc.GetPaperColor()];
result.paperTypeDesc[1] = [NSNumber numberWithInt:imgLoc.GetPaperItems()] ;
result.paperTypeDesc[2] = [NSNumber numberWithInt:imgLoc.GetPaperLocLength()] ;
Mat rgbMat;
cvtColor(roiRotImage, rgbMat, COLOR_BGRA2RGB);
Mat mediaMat;
cv::medianBlur(rgbMat, mediaMat, 3);
Mat meanMat;
cv::blur(mediaMat, meanMat, cv::Size(3, 3));
int xs[ITEM_SIZE];
int ys[ITEM_SIZE];
int totalPt = 0;//ITEM_SIZE;
for (int i = 0; i < ITEM_SIZE; ++i) {
if (i >= positions.size())
break;
xs[i] = positions[i].x;
ys[i] = positions[i].y;
if (xs[i] > 0 && ys[i] > 0) {
totalPt += 1;
}
}
for (int i = 0; i < totalPt - 1; ++i) {
cv::Point pt(xs[i], ys[i]);
cv::Rect roi(pt.x - 5, pt.y - 5, 10, 10);
Mat roiRgbMat(meanMat, roi);
Mat hsvMat, labMat;
cvtColor(roiRgbMat, hsvMat, COLOR_RGB2HSV);
cvtColor(roiRgbMat, labMat, COLOR_RGB2Lab);
Scalar avgHsv = mean(hsvMat);
Scalar avgLab = mean(labMat);
result.paperAnalResults[i][0] = [NSNumber numberWithDouble:avgHsv.val[0]] ;
result.paperAnalResults[i][1] = [NSNumber numberWithDouble:avgHsv.val[1]] ;
result.paperAnalResults[i][2] = [NSNumber numberWithDouble:avgHsv.val[2]] ;
result.paperAnalResults[i][3] = [NSNumber numberWithDouble:avgLab.val[0]] ;
result.paperAnalResults[i][4] = [NSNumber numberWithDouble:avgLab.val[1]] ;
result.paperAnalResults[i][5] = [NSNumber numberWithDouble:avgLab.val[2]] ;
}
}
return result;
}
@end