导入 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。
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
#ifndef __COMPARER_H__
|
||||
#define __COMPARER_H__
|
||||
#include "ContourSelector.h"
|
||||
template <GF_FLAG T,bool isGreater=true>
|
||||
struct Comparer
|
||||
{
|
||||
bool operator()(const ContourSelector::PairTExtend& s1, const ContourSelector::PairTExtend& s2)
|
||||
{
|
||||
ContourGfExtend *pContourGf1=s1.second;
|
||||
ContourGfExtend *pContourGf2=s2.second;
|
||||
double gfValue1=0.0;
|
||||
double gfValue2=0.0;
|
||||
switch (T)
|
||||
{
|
||||
case Perimeter:
|
||||
{
|
||||
gfValue1 = pContourGf1->getContourPerimeter();
|
||||
gfValue2 = pContourGf2->getContourPerimeter();
|
||||
}
|
||||
break;
|
||||
case Area:
|
||||
{
|
||||
gfValue1 = pContourGf1->getContourArea();
|
||||
gfValue2 = pContourGf2->getContourArea();
|
||||
}
|
||||
break;
|
||||
case CenterX:
|
||||
{
|
||||
gfValue1 = pContourGf1->getContourCenter().x;
|
||||
gfValue2 = pContourGf2->getContourCenter().x;
|
||||
}
|
||||
break;
|
||||
case CenterY:
|
||||
{
|
||||
gfValue1 = pContourGf1->getContourCenter().y;
|
||||
gfValue2 = pContourGf2->getContourCenter().y;
|
||||
}
|
||||
break;
|
||||
case LeftTopX:
|
||||
{
|
||||
gfValue1 = pContourGf1->getLeftTop().y;
|
||||
gfValue2 = pContourGf2->getLeftTop().y;
|
||||
}
|
||||
break;
|
||||
case LeftTopY:
|
||||
{
|
||||
gfValue1 = pContourGf1->getLeftTop().y;
|
||||
gfValue2 = pContourGf2->getLeftTop().y;
|
||||
}
|
||||
break;
|
||||
case RightBottomX:
|
||||
{
|
||||
gfValue1 = pContourGf1->getRightBottom().x;
|
||||
gfValue2 = pContourGf2->getRightBottom().x;
|
||||
}
|
||||
break;
|
||||
case RightBottomY:
|
||||
{
|
||||
gfValue1 = pContourGf1->getRightBottom().y;
|
||||
gfValue2 = pContourGf2->getRightBottom().y;
|
||||
}
|
||||
break;
|
||||
case AspectRatio: //长宽比
|
||||
{
|
||||
gfValue1=pContourGf1->getContourAspectRatio();
|
||||
gfValue2=pContourGf2->getContourAspectRatio();
|
||||
}
|
||||
break;
|
||||
case Rectangularity: //矩形度
|
||||
{
|
||||
gfValue1=pContourGf1->getContourRectangularity();
|
||||
gfValue2=pContourGf2->getContourRectangularity();
|
||||
}
|
||||
break;
|
||||
//灰度值
|
||||
case GrayValue:
|
||||
{
|
||||
gfValue1=pContourGf1->getContourGrayValue();
|
||||
gfValue2=pContourGf2->getContourGrayValue();
|
||||
}
|
||||
break;
|
||||
case Width:
|
||||
{
|
||||
gfValue1=pContourGf1->getSize().width;
|
||||
gfValue2=pContourGf2->getSize().width;
|
||||
}
|
||||
break;
|
||||
case Height:
|
||||
{
|
||||
gfValue1=pContourGf1->getSize().height;
|
||||
gfValue2=pContourGf2->getSize().height;
|
||||
}
|
||||
break;
|
||||
case RedPercentage:
|
||||
{
|
||||
gfValue1=pContourGf1->getColorPercentage(0);
|
||||
gfValue2=pContourGf2->getColorPercentage(0);
|
||||
}
|
||||
break;
|
||||
case GreenPercentage:
|
||||
{
|
||||
gfValue1=pContourGf1->getColorPercentage(1);
|
||||
gfValue2=pContourGf2->getColorPercentage(1);
|
||||
}
|
||||
break;
|
||||
case BluePercentage:
|
||||
{
|
||||
gfValue1=pContourGf1->getColorPercentage(2);
|
||||
gfValue2=pContourGf2->getColorPercentage(2);
|
||||
}
|
||||
break;
|
||||
case RotRectArea:
|
||||
{
|
||||
gfValue1 = pContourGf1->getRotatedRect().size.height * pContourGf1->getRotatedRect().size.width;
|
||||
gfValue2 = pContourGf2->getRotatedRect().size.height * pContourGf2->getRotatedRect().size.width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isGreater)
|
||||
{
|
||||
return gfValue1 > gfValue2; //从da到xiao排序
|
||||
}
|
||||
else
|
||||
{
|
||||
return gfValue1 < gfValue2;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
#ifndef __CONTOURGF_H__
|
||||
#define __CONTOURGF_H__
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/core/core.hpp>
|
||||
//#include <opencv2/core/types_c.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
enum GF_FLAG
|
||||
{
|
||||
Perimeter,
|
||||
Area,
|
||||
CenterX,
|
||||
CenterY,
|
||||
LeftTopX,
|
||||
LeftTopY,
|
||||
RightBottomX,
|
||||
RightBottomY,
|
||||
AspectRatio,
|
||||
Rectangularity,
|
||||
GrayValue,
|
||||
Width,
|
||||
Height,
|
||||
RedPercentage,
|
||||
GreenPercentage,
|
||||
BluePercentage,
|
||||
RotRectArea
|
||||
};
|
||||
|
||||
class ContourGf {
|
||||
|
||||
private:
|
||||
|
||||
int contourPerimeter; //
|
||||
int contourArea; //
|
||||
cv::Point contourCenter; //
|
||||
cv::Point leftTop;
|
||||
cv::Point rightBottom;
|
||||
|
||||
public:
|
||||
|
||||
ContourGf()
|
||||
{
|
||||
// TODO Auto-generated constructor stub
|
||||
memset(&contourCenter,0,sizeof(cv::Point));
|
||||
memset(&leftTop,0,sizeof(cv::Point));
|
||||
memset(&rightBottom,0,sizeof(cv::Point));
|
||||
contourPerimeter=0;
|
||||
contourArea=0;
|
||||
|
||||
}
|
||||
|
||||
ContourGf(int contourPerimeter,
|
||||
int contourArea,
|
||||
cv::Point& contourCenter,
|
||||
cv::Point& leftTop,
|
||||
cv::Point& rightBottom)
|
||||
{
|
||||
|
||||
this->contourPerimeter = contourPerimeter;
|
||||
this->contourArea = contourArea;
|
||||
this->contourCenter = contourCenter;
|
||||
this->leftTop = leftTop;
|
||||
this->rightBottom = rightBottom;
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
int getContourPerimeter()
|
||||
{
|
||||
return contourPerimeter;
|
||||
}
|
||||
|
||||
void setContourPerimeter(int contourPerimeter)
|
||||
{
|
||||
this->contourPerimeter = contourPerimeter;
|
||||
}
|
||||
|
||||
int getContourArea()
|
||||
{
|
||||
return contourArea;
|
||||
}
|
||||
|
||||
void setContourArea(int contourArea)
|
||||
{
|
||||
this->contourArea = contourArea;
|
||||
}
|
||||
|
||||
cv::Point getContourCenter()
|
||||
{
|
||||
return contourCenter;
|
||||
}
|
||||
|
||||
void setContourCenter(cv::Point& contourCenter)
|
||||
{
|
||||
this->contourCenter = contourCenter;
|
||||
}
|
||||
|
||||
void setContourCenter(int x, int y)
|
||||
{
|
||||
this->contourCenter.x=x;
|
||||
this->contourCenter.y=y;
|
||||
}
|
||||
|
||||
cv::Point getLeftTop()
|
||||
{
|
||||
return leftTop;
|
||||
}
|
||||
|
||||
void setLeftTop(cv::Point& leftTop)
|
||||
{
|
||||
this->leftTop = leftTop;
|
||||
}
|
||||
|
||||
void setLeftTop(int x, int y)
|
||||
{
|
||||
this->leftTop.x=x;
|
||||
this->leftTop.y=y;
|
||||
}
|
||||
|
||||
cv::Point getRightBottom()
|
||||
{
|
||||
return rightBottom;
|
||||
}
|
||||
|
||||
void setRightBottom(cv::Point& rightBottom)
|
||||
{
|
||||
this->rightBottom = rightBottom;
|
||||
}
|
||||
|
||||
void setRightBottom(int x, int y)
|
||||
{
|
||||
this->rightBottom.x=x;
|
||||
this->rightBottom.y=y;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,130 @@
|
||||
#ifndef __CONTOURGF_EXTEND_H__
|
||||
#define __CONTOURGF_EXTEND_H__
|
||||
#include "ContourGf.h"
|
||||
|
||||
class ContourGfExtend :public ContourGf
|
||||
{
|
||||
public:
|
||||
ContourGfExtend():ContourGf()
|
||||
{
|
||||
contourAspectRatio=0.0;
|
||||
contourRectangularity=0.0;
|
||||
contourGrayValue=0;
|
||||
colorPercentage[0]=0.0;
|
||||
colorPercentage[1]=0.0;
|
||||
colorPercentage[2]=0.0;
|
||||
}
|
||||
ContourGfExtend(double contourAspectRatio,
|
||||
double contourRectangularity,
|
||||
int contourGrayValue):ContourGf()
|
||||
{
|
||||
this->contourAspectRatio=contourAspectRatio;
|
||||
this->contourRectangularity=contourRectangularity;
|
||||
this->contourGrayValue=contourGrayValue;
|
||||
}
|
||||
ContourGfExtend(double contourAspectRatio,
|
||||
double contourRectangularity,
|
||||
int contourGrayValue,
|
||||
int contourPerimeter,
|
||||
int contourArea,
|
||||
cv::Point& contourCenter,
|
||||
cv::Point& leftTop,
|
||||
cv::Point& rightBottom)
|
||||
:
|
||||
ContourGf(contourPerimeter,
|
||||
contourArea,
|
||||
contourCenter,
|
||||
leftTop,
|
||||
rightBottom)
|
||||
{
|
||||
this->contourAspectRatio=contourAspectRatio;
|
||||
this->contourRectangularity=contourRectangularity;
|
||||
this->contourGrayValue=contourGrayValue;
|
||||
}
|
||||
|
||||
|
||||
~ContourGfExtend(){}
|
||||
private:
|
||||
|
||||
double contourAspectRatio;
|
||||
double contourRectangularity;
|
||||
int contourGrayValue;
|
||||
cv::RotatedRect rotRect;
|
||||
int contourIndex;
|
||||
cv::Size size;//选择矩形的宽和高
|
||||
double colorPercentage[3];//颜色比例,rgb
|
||||
public:
|
||||
void setColorPercentage(double v1,double v2,double v3)
|
||||
{
|
||||
colorPercentage[0]=v1;
|
||||
colorPercentage[1]=v2;
|
||||
colorPercentage[2]=v3;
|
||||
}
|
||||
double getColorPercentage(int vIndex)
|
||||
{
|
||||
return colorPercentage[vIndex];
|
||||
}
|
||||
double getContourAspectRatio()
|
||||
{
|
||||
return contourAspectRatio;
|
||||
}
|
||||
|
||||
void setContourAspectRatio(double contourAspectRatio)
|
||||
{
|
||||
this->contourAspectRatio=contourAspectRatio;
|
||||
}
|
||||
|
||||
double getContourRectangularity()
|
||||
{
|
||||
return contourRectangularity;
|
||||
}
|
||||
|
||||
void setContourRectangularity(double contourRectangularity)
|
||||
{
|
||||
this->contourRectangularity=contourRectangularity;
|
||||
}
|
||||
|
||||
int getContourGrayValue()
|
||||
{
|
||||
return contourGrayValue;
|
||||
}
|
||||
|
||||
void setContourGrayValue(int contourGrayValue)
|
||||
{
|
||||
this->contourGrayValue=contourGrayValue;
|
||||
}
|
||||
|
||||
const cv::RotatedRect& getRotatedRect()
|
||||
{
|
||||
return rotRect;
|
||||
}
|
||||
|
||||
void setRotatedRect(const cv::RotatedRect& rotRect)
|
||||
{
|
||||
this->rotRect=rotRect;
|
||||
}
|
||||
const int getRotRectArea()
|
||||
{
|
||||
return rotRect.size.width * rotRect.size.height;
|
||||
}
|
||||
void setContourIndex(int contourIndex)
|
||||
{
|
||||
this->contourIndex=contourIndex;
|
||||
}
|
||||
|
||||
int getContourIndex()
|
||||
{
|
||||
return contourIndex;
|
||||
}
|
||||
|
||||
void setSize(cv::Size size)
|
||||
{
|
||||
this->size=size;
|
||||
}
|
||||
|
||||
const cv::Size& getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,190 @@
|
||||
#include "ContourSelector.h"
|
||||
|
||||
/*
|
||||
#include <android/log.h>
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
#define LOG_TAG "NDK"
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||||
#define ITEM_SIZE 16
|
||||
*/
|
||||
|
||||
#define MIN_VALUE 5
|
||||
ContourSelector::ContourSelector()
|
||||
{
|
||||
|
||||
}
|
||||
ContourSelector:: ~ContourSelector()
|
||||
{
|
||||
|
||||
}
|
||||
void ContourSelector::CalContoursGf(Mat & src,
|
||||
ContoursTExtend & contours,
|
||||
VectorPT &vectorPT)
|
||||
{
|
||||
for (unsigned int i = 0; i < contours.size(); i++)
|
||||
{
|
||||
ContourGfExtend *pContourGf = new ContourGfExtend();
|
||||
vector<cv::Point> &pContour = contours.at(i);
|
||||
cv::Rect rect = boundingRect(pContour);
|
||||
cv::RotatedRect roteRect=minAreaRect(pContour);
|
||||
pContourGf->setContourArea((int)contourArea(pContour));
|
||||
pContourGf->setContourPerimeter((int)arcLength(pContour, true));
|
||||
pContourGf->setRotatedRect(roteRect);
|
||||
pContourGf->setContourIndex(i);
|
||||
int width=max(roteRect.size.height,roteRect.size.width);
|
||||
int height=min(roteRect.size.height,roteRect.size.width);
|
||||
//pContourGf->setContourArea(width*height);
|
||||
pContourGf->setSize(cv::Size(rect.width,rect.height));
|
||||
pContourGf->setContourAspectRatio((double)height/width);//�����
|
||||
pContourGf->setContourRectangularity((double)pContourGf->getContourArea()/(width*height));//���ζ�
|
||||
pContourGf->setContourCenter((int)roteRect.center.x, (int)roteRect.center.y);
|
||||
pContourGf->setLeftTop(rect.x, rect.y);
|
||||
pContourGf->setRightBottom(rect.x + rect.width, rect.y + rect.height);
|
||||
|
||||
cv::Rect roi((int)roteRect.center.x,(int)roteRect.center.y,MIN_VALUE,MIN_VALUE);
|
||||
if (roi.x+MIN_VALUE>(src.cols-1)
|
||||
||roi.y+MIN_VALUE>(src.rows-1)
|
||||
||width<MIN_VALUE
|
||||
||height<MIN_VALUE)
|
||||
{
|
||||
delete pContourGf;
|
||||
continue;
|
||||
}
|
||||
Mat roiSrc(src,roi);
|
||||
cv::Scalar avg=mean(roiSrc);
|
||||
double avgSum=avg.val[0]+avg.val[1]+avg.val[2];
|
||||
double bp=avg.val[0]/avgSum;
|
||||
double gp=avg.val[1]/avgSum;
|
||||
double rp=avg.val[2]/avgSum;
|
||||
pContourGf->setColorPercentage(rp,gp,bp);
|
||||
pContourGf->setContourGrayValue(avgSum/3);
|
||||
PairTExtend v ;
|
||||
v.first = &pContour;
|
||||
v.second = pContourGf;
|
||||
|
||||
vectorPT.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
void ContourSelector::SelectObj(const VectorPT& vectorPT1,
|
||||
VectorPT& vectorPT2,
|
||||
const vector<int>&indices)
|
||||
{
|
||||
int count=vectorPT1.size();
|
||||
for (int i=0;i<indices.size();++i)
|
||||
{
|
||||
int index=indices[i];
|
||||
if (index>=0&&index<count)
|
||||
{
|
||||
vectorPT2.push_back(vectorPT1[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContourSelector::SelectContour(VectorPT& vectorPT1,
|
||||
VectorPT& vectorPT2,
|
||||
double minValue,
|
||||
double maxValue,
|
||||
GF_FLAG gf)
|
||||
{
|
||||
VectorPT::iterator it=vectorPT1.begin();
|
||||
for (;it!=vectorPT1.end();++it)
|
||||
{
|
||||
ContourGfExtend *pContourGf=it->second;
|
||||
double gfValue=0.0;
|
||||
switch (gf)
|
||||
{
|
||||
case Perimeter:
|
||||
{
|
||||
gfValue = pContourGf->getContourPerimeter();
|
||||
}
|
||||
break;
|
||||
case Area:
|
||||
{
|
||||
gfValue = pContourGf->getContourArea();
|
||||
}
|
||||
break;
|
||||
case CenterX:
|
||||
{
|
||||
gfValue = pContourGf->getContourCenter().x;
|
||||
}
|
||||
break;
|
||||
case CenterY:
|
||||
{
|
||||
gfValue = pContourGf->getContourCenter().y;
|
||||
}
|
||||
break;
|
||||
case LeftTopX:
|
||||
{
|
||||
gfValue = pContourGf->getLeftTop().x;
|
||||
}
|
||||
break;
|
||||
case LeftTopY:
|
||||
{
|
||||
gfValue = pContourGf->getLeftTop().y;
|
||||
}
|
||||
break;
|
||||
case RightBottomX:
|
||||
{
|
||||
gfValue = pContourGf->getRightBottom().x;
|
||||
}
|
||||
break;
|
||||
case RightBottomY:
|
||||
{
|
||||
gfValue = pContourGf->getRightBottom().y;
|
||||
}
|
||||
break;
|
||||
case AspectRatio:
|
||||
{
|
||||
gfValue=pContourGf->getContourAspectRatio();
|
||||
}
|
||||
break;
|
||||
case Rectangularity:
|
||||
{
|
||||
gfValue=pContourGf->getContourRectangularity();
|
||||
}
|
||||
break;
|
||||
//�Ҷ�ֵ
|
||||
case GrayValue:
|
||||
{
|
||||
gfValue=pContourGf->getContourGrayValue();
|
||||
}
|
||||
break;
|
||||
case Width:
|
||||
{
|
||||
gfValue=pContourGf->getSize().width;
|
||||
}
|
||||
break;
|
||||
case Height:
|
||||
{
|
||||
gfValue=pContourGf->getSize().height;
|
||||
}
|
||||
break;
|
||||
case RedPercentage:
|
||||
{
|
||||
gfValue=pContourGf->getColorPercentage(0);
|
||||
}
|
||||
break;
|
||||
case GreenPercentage:
|
||||
{
|
||||
gfValue=pContourGf->getColorPercentage(1);
|
||||
}
|
||||
break;
|
||||
case BluePercentage:
|
||||
{
|
||||
gfValue=pContourGf->getColorPercentage(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (gfValue>=minValue&&gfValue<=maxValue)
|
||||
{
|
||||
PairTExtend pt;
|
||||
pt.first=it->first;
|
||||
pt.second=it->second;
|
||||
vectorPT2.push_back(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __CONTOURSELECTOR_H__
|
||||
#define __CONTOURSELECTOR_H__
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "ContourGfExtend.h"
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
class ContourSelector
|
||||
{
|
||||
|
||||
public:
|
||||
typedef pair<vector<cv::Point>*,ContourGfExtend*> PairTExtend;
|
||||
typedef vector<PairTExtend> VectorPT;
|
||||
typedef vector<vector<cv::Point> > ContoursTExtend;
|
||||
typedef vector<cv::Vec4i> HierarchyTExtend;
|
||||
public:
|
||||
ContourSelector();
|
||||
virtual ~ContourSelector();
|
||||
public:
|
||||
void CalContoursGf(Mat & src,
|
||||
ContoursTExtend & contours,
|
||||
VectorPT &vectorPT);
|
||||
|
||||
void SelectObj(const VectorPT& vectorPT1,
|
||||
VectorPT& vectorPT2,
|
||||
const vector<int>&indices);
|
||||
|
||||
void SelectContour(VectorPT& vectorPT1,
|
||||
VectorPT& vectorPT2,
|
||||
double minValue,
|
||||
double maxValue,
|
||||
GF_FLAG gf);
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "ImageLocation.h"
|
||||
|
||||
|
||||
ImageLocation::ImageLocation()
|
||||
{
|
||||
score=0;
|
||||
}
|
||||
|
||||
ImageLocation::~ImageLocation()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
double ImageLocation::GetDefinition()
|
||||
{
|
||||
return imgLocDryChemistry.GetDefinition();
|
||||
}
|
||||
|
||||
int ImageLocation::GetPaperColor()
|
||||
{
|
||||
return imgLocDryChemistry.GetLocatorColor();
|
||||
}
|
||||
int ImageLocation::GetPaperItems()
|
||||
{
|
||||
return imgLocDryChemistry.GetPaperItems();//14,12,11,,,,
|
||||
}
|
||||
int ImageLocation::GetPaperLocLength()
|
||||
{
|
||||
return imgLocDryChemistry.GetLocatorType();//2/3/0
|
||||
}
|
||||
|
||||
Mat& ImageLocation::GetPaperImg()
|
||||
{
|
||||
return imgLocDryChemistry.GetPaperImg();
|
||||
}
|
||||
|
||||
|
||||
cv::Mat ImageLocation::LocationProc(cv::Mat& image, cv::Rect roi, bool bDraw,cv::Scalar& paperParams,
|
||||
cv::Scalar& wbAvgRgb, std::vector<cv::Point>& roiPositions, cv::Mat& rotRoiImage)
|
||||
{
|
||||
score=0;
|
||||
roiPositions.clear();
|
||||
int err=-1;
|
||||
|
||||
cv::Mat r = imgLocDryChemistry.GetPosition(image, roi, bDraw, wbAvgRgb,
|
||||
roiPositions);
|
||||
err = imgLocDryChemistry.GetLastError();
|
||||
|
||||
wbAvgRgb.val[3] = err;
|
||||
if (err == 0) {
|
||||
|
||||
paperParams.val[0] = imgLocDryChemistry.GetLocatorColor();
|
||||
paperParams.val[1] = imgLocDryChemistry.GetLocatorType();
|
||||
paperParams.val[2] = imgLocDryChemistry.GetPaperItems();
|
||||
|
||||
cv::Mat(image,roi).copyTo(rotRoiImage);
|
||||
score= imgLocDryChemistry.GetScore();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef __IMAGELOCATION_H__
|
||||
#define __IMAGELOCATION_H__
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "ImgLocateDryChemistry.h"
|
||||
|
||||
class ImageLocation
|
||||
{
|
||||
public:
|
||||
|
||||
ImageLocation();
|
||||
virtual ~ImageLocation();
|
||||
private:
|
||||
ImgLocateDryChemistry imgLocDryChemistry;
|
||||
int score;
|
||||
public:
|
||||
|
||||
|
||||
/*
|
||||
*be just used for all
|
||||
*/
|
||||
Mat& GetPaperImg();
|
||||
/*
|
||||
*be just used for all
|
||||
*/
|
||||
double GetDefinition();
|
||||
|
||||
/*
|
||||
*be just used for ImageLocation14i
|
||||
*/
|
||||
int GetPaperColor();//RED, GREEN,BLUE
|
||||
|
||||
int GetPaperItems();//14,12,11,10
|
||||
|
||||
int GetPaperLocLength();//2/3/0
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/*get the score of the location */
|
||||
/************************************************************************/
|
||||
int GetScore()
|
||||
{
|
||||
return score;
|
||||
}
|
||||
|
||||
public:
|
||||
cv::Mat LocationProc(cv::Mat& image, cv::Rect roi, bool bDraw,cv::Scalar& paperParams,
|
||||
cv::Scalar& wbAvgRgb, std::vector<cv::Point>& roiPositions, cv::Mat& rotRoiImage);
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <vector>
|
||||
#include "ContourSelector.h"
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
|
||||
class PaperConfig {
|
||||
public:
|
||||
PaperConfig();
|
||||
PaperConfig(int pst,int i, int s, double f, double st, double d, double r, double l);
|
||||
virtual ~PaperConfig();
|
||||
public:
|
||||
int itemsNum;
|
||||
int paperSpatialType;
|
||||
int slicesNum;
|
||||
double firstPos; //real first postion == firstPos * avg slice's width
|
||||
double step;
|
||||
double distTimes;//(distance of 2 center points ) % ( height of paper) such as 21.2 (106.5 % 5 )
|
||||
double whRRatio;//big locator : 2 / 3
|
||||
double whLRatio;//small locator : 0.6
|
||||
void Init();
|
||||
};
|
||||
|
||||
class ImgLocateDryChemistry
|
||||
{
|
||||
public:
|
||||
ImgLocateDryChemistry();
|
||||
~ImgLocateDryChemistry();
|
||||
|
||||
private:
|
||||
enum BlockItems{
|
||||
BI_14 = 14,
|
||||
BI_13 = 13,
|
||||
BI_12 = 12,
|
||||
BI_11 = 11,
|
||||
BI_10 = 10,
|
||||
BI_9 = 9,
|
||||
BI_8 = 8,
|
||||
BI_7 = 7,
|
||||
BI_6 = 6,
|
||||
BI_5 = 5,
|
||||
BI_4 = 4,
|
||||
};
|
||||
enum BigLocatorType{
|
||||
BLT_SHORT = 0,//10mm
|
||||
BLT_LONG = 1,//15mm
|
||||
};
|
||||
|
||||
//locator color: Red, Green, Blue
|
||||
enum LocatorColorClassification{
|
||||
LCC_UNKNOWN = 0,
|
||||
LCC_RED = 1,
|
||||
LCC_GREEN = 2,
|
||||
LCC_BLUE = 3,
|
||||
};
|
||||
|
||||
|
||||
enum PaperSpatialType{
|
||||
PST_UNKNOWN = 0,
|
||||
|
||||
PST_14_S = 1, // ON
|
||||
PST_14_L = 2, // ON
|
||||
|
||||
PST_13_S = 3,
|
||||
PST_13_L = 4,
|
||||
|
||||
PST_12_S = 5, // ON
|
||||
PST_12_L = 6,
|
||||
|
||||
PST_11_S = 7,
|
||||
PST_11_L = 8, // ON
|
||||
|
||||
PST_10_S = 9, // ON
|
||||
PST_10_L = 10,
|
||||
|
||||
PST_9_S = 11,
|
||||
PST_9_L = 12, // ON
|
||||
|
||||
PST_8_S = 13, // ON
|
||||
PST_8_L = 14,
|
||||
|
||||
PST_7_S = 15,
|
||||
PST_7_L = 16, // ON
|
||||
|
||||
PST_6_S = 17, // ON
|
||||
PST_6_L = 18,
|
||||
|
||||
PST_5_S = 19,
|
||||
PST_5_L = 20, // ON
|
||||
|
||||
PST_4_S = 21, // ON
|
||||
PST_4_L = 22,
|
||||
};
|
||||
|
||||
|
||||
Mat src; /*保存原始图片 */
|
||||
Mat roiSrc; /*由SRC裁剪而来,大小ROI */
|
||||
Mat hsv; /*由rgb convert而来 */
|
||||
Mat rgb; /*由roiSrc convert而来 */
|
||||
Mat paperImg; /*定位出的进一步 裁剪后的图片 */
|
||||
|
||||
int recode; /* */
|
||||
int score; /* */
|
||||
|
||||
int locatorColor; /*定位块颜色类型 1: green 2:red 3:blue */
|
||||
int paperItems;
|
||||
int paperSpatialType;/*试纸类型*/
|
||||
|
||||
// int expectedPaperType; /* */
|
||||
double avgDist; /* */
|
||||
double totalDist; /* */
|
||||
double distTimes; /* */
|
||||
|
||||
bool bRot; /* */
|
||||
double topDefinitionValue;/* */
|
||||
|
||||
ContourSelector cs; /* 轮廓选择器 */
|
||||
ContourSelector::VectorPT vecPt; /* */
|
||||
ContourSelector::PairTExtend lRectContour; /* 左定位块外包轮廓 */
|
||||
ContourSelector::PairTExtend rRectContour; /* */
|
||||
|
||||
cv::RotatedRect lRotRect; /* 左定位块 旋转矩形 */
|
||||
cv::RotatedRect rRotRect; /* */
|
||||
int lRotRectWidth; /* */
|
||||
int rRotRectWidth; /* */
|
||||
int lRotRectHeight; /* */
|
||||
int rRotRectHeight; /* */
|
||||
|
||||
int paperHeight; /* */
|
||||
|
||||
map<int, PaperConfig*> mapPaperConfig;
|
||||
PaperConfig* paperConfig;
|
||||
|
||||
public:
|
||||
Mat& GetPosition(Mat& s, cv::Rect& roi, bool bDraw, cv::Scalar& wbAvgRgb, vector<cv::Point>&roiPositions);
|
||||
int GetLastError() { return recode; }
|
||||
Mat& GetPaperImg() { return paperImg; }
|
||||
int GetLocatorColor() { return locatorColor; }
|
||||
int GetLocatorType();
|
||||
int GetPaperItems();
|
||||
double GetDefinition() { return topDefinitionValue; }
|
||||
int GetPaperHeight() { return paperHeight; }
|
||||
int GetScore() { return score; }
|
||||
|
||||
private:
|
||||
int analyseLocatorColor(Mat& sImg, double& slope);
|
||||
bool analyseDefinition(Mat& sImg , cv::Rect& roi);
|
||||
Mat& warpAffineImg(Mat &img);
|
||||
|
||||
// bool verifyDistance();
|
||||
int verifyPaperConfig(double distRadio,double areaRadio);
|
||||
|
||||
void initPaperConfig();
|
||||
void savePaperImg();
|
||||
|
||||
bool calGrayImgDefinition(Mat &img,double m,int u);
|
||||
double calImgDefinition(Mat &img, double &diff, double &avg, int &lowLines, int &upLines);
|
||||
int readLocatorColor(ContourGfExtend* pContourGfE);//0: green 1:red 2:blue -1:other
|
||||
|
||||
void releaseContoursGf(ContourSelector::VectorPT& vectorPt, int code = 0);
|
||||
int processImage(Mat& sImg, Mat& b, Mat&v, cv::Rect& roi, bool useSThres, bool bDraw, cv::Scalar& wbAvgRgb, vector<cv::Point>&roiPositions);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// ImgResult.h
|
||||
// XuXuCheck
|
||||
//
|
||||
// Created by henseycai on 2025/6/26.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ImgResult : NSObject
|
||||
|
||||
@property UIImage* srcImg;
|
||||
@property UIImage* roiImg;
|
||||
//@property NSMutableArray<NSNumber*> *paperWbValue;
|
||||
//@property NSMutableArray<NSNumber*> *paperTypeDesc;
|
||||
@property NSMutableArray *paperWbValue;
|
||||
@property NSMutableArray *paperTypeDesc;
|
||||
@property NSMutableArray *paperAnalResults;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// ImgResult.m
|
||||
// XuXuCheck
|
||||
//
|
||||
// Created by henseycai on 2025/6/26.
|
||||
//
|
||||
|
||||
#import "ImgResult.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation ImgResult
|
||||
- (instancetype)init{
|
||||
self = [super init];
|
||||
if(self){
|
||||
_paperWbValue = [NSMutableArray arrayWithObjects:@[@0,@0,@0,@0], nil];
|
||||
_paperTypeDesc = [NSMutableArray arrayWithObjects:@[@0,@0,@0,@0], nil];
|
||||
_paperAnalResults = [NSMutableArray arrayWithObjects:
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//10
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil],//1
|
||||
[NSMutableArray arrayWithObjects:@0.0, @0.0, @0.0, @0.0, @0.0, @0.0,nil]//16
|
||||
,nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// OpencvWrapper.h
|
||||
// XuXuCheck
|
||||
//
|
||||
// Created by henseycai on 2025/5/26.
|
||||
//
|
||||
|
||||
// OpenCVWrapper.h
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ImgResult.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@interface OpenCVWrapper : NSObject
|
||||
|
||||
+ (UIImage *)toGrayscale:(UIImage *)image;
|
||||
+ (UIImage *)gaussianBlur:(UIImage *)image: (int)blurAmount;
|
||||
+ (ImgResult *)analysisImage:(UIImage *)image;
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// 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
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// PrefixHeader.pch
|
||||
// XuXuCheck
|
||||
//
|
||||
// Created by henseycai on 2025/5/26.
|
||||
//
|
||||
|
||||
#ifndef PrefixHeader_pch
|
||||
#define PrefixHeader_pch
|
||||
|
||||
// Include any system framework and library headers here that should be included in all compilation units.
|
||||
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
|
||||
#ifdef __cplusplus
|
||||
#include <opencv2/opencv.hpp>
|
||||
#endif
|
||||
#endif /* PrefixHeader_pch */
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Utils.h
|
||||
*
|
||||
* Created on: 2018-1-14
|
||||
* Author: neo
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H_
|
||||
#define UTILS_H_
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <vector>
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
void Whitebalance(Mat src,Point wbPt);
|
||||
bool pred(const std::pair<int, int>& lhs,const std::pair<int, int>& rhs);
|
||||
|
||||
int GetHModal(Mat h);
|
||||
#endif /* UTILS_H_ */
|
||||
Reference in New Issue
Block a user