#include "ReferenceProc.h"
//-------------------------------------------------------------------------------
// コンストラクタ
CReferenceProc::CReferenceProc(void)
{
m_Casmatch = new CDetectCasmatch;
m_Macbeth = new CDetectMacbeth;
m_ccmCL = new CMRegressionLinear;
m_ccmLX = new CMRegressionRGB (LIN_XYZ_CONVERT_DIM);
m_ccmXD = new CMRegressionRGB (XYZ_DISP_CONVERT_DIM);
m_crgbRC = NULL;
m_lrgbRC = NULL;
m_crgbRM = NULL;
m_lrgbRM = NULL;
m_xyzM = NULL;
}
//-------------------------------------------------------------------------------
// デストラクタ
CReferenceProc::~CReferenceProc(void)
{
SAFE_DELETE(m_Casmatch);
SAFE_DELETE(m_Macbeth);
SAFE_DELETE(m_ccmCL);
SAFE_DELETE(m_ccmLX);
SAFE_DELETE(m_ccmXD);
SAFE_RELEASEMAT(m_crgbRC);
SAFE_RELEASEMAT(m_lrgbRC);
SAFE_RELEASEMAT(m_crgbRM);
SAFE_RELEASEMAT(m_lrgbRM);
SAFE_RELEASEMAT(m_xyzM);
}
//-------------------------------------------------------------------------------
// 初期化
bool CReferenceProc::Init()
{
CALL(m_Casmatch->Init());
CALL(m_Macbeth->Init());
SAFE_RELEASEMAT(m_xyzM);
#ifdef XYZ_FROM_SPECTRAL_DATA
m_xyzM = this->GenMacbethXYZSpect();
#else
m_xyzM = GLoadCsv(MEASURED_MACBETH_XYZ, 24, 3, 2, 2);
#endif
CALL(m_xyzM);
// XYZ→ディスプレイRGB 変換行列
CvMat *monitorRGB = GLoadCsv(MONITOR_RGB, 4913, 3, 2, 1);
CALL(monitorRGB);
CvMat *monitorXYZ = GLoadCsv(MONITOR_XYZ, 4913, 3, 2, 1);
CALL(monitorXYZ);
#ifdef SHOW_REGRESSION_COEF
printf("ccmXD ");
#endif // SHOW_REGRESSION_COEF
CALL(m_ccmXD->CalcCoef(monitorXYZ, monitorRGB));
CALL(m_ccmXD->CalcError(monitorXYZ, monitorRGB));
// m_ccmXD->DrawGraph4913(monitorRGB, monitorXYZ);
SAFE_RELEASEMAT(monitorRGB);
SAFE_RELEASEMAT(monitorXYZ);
return true;
}
//-------------------------------------------------------------------------------
// 分光データからマクベスのXYZを生成する
CvMat *CReferenceProc::GenMacbethXYZSpect()
{
// データの読み込み
CvMat *light = GLoadCsv(LIGHTSOURCE_SPECTRAL, SPECT_DIM, 1, 2, 2);
CALL(light);
CvMat *macbeth = GLoadCsv(MACBETH_SPECTRAL, SPECT_DIM, 24, 2, 2);
CALL(macbeth);
CvMat *cmf = GLoadCsv(CMF_SPECTRAL, SPECT_DIM, 3, 2, 2);
CALL(cmf);
// 線光源分光分布 列コピー演算用ベクトル
double value[24] = {0.0};
CvMat ones = cvMat(1, 24, CV_64F, value);
cvAddS(&ones, cvScalar(1.0), &ones);
// 線光源分光分布 24列コピー
CvMat *light24 = cvCreateMat(SPECT_DIM, 24, CV_64F);
cvMatMul(light, &ones, light24);
// マクベスの分光反射率と光源を掛ける
CvMat *refMacbeth = cvCreateMat(SPECT_DIM, 24, CV_64F);
cvMul(macbeth, light24, refMacbeth);
// 完全白色板 Y=100 とする正規化係数を算出
CvMat *xyzWhite = cvCreateMat(1, 3, CV_64F);
cvGEMM(light, cmf, 1.0, NULL, 1.0, xyzWhite, CV_GEMM_A_T);
double k = 100.0 / cvmGet(xyzWhite, 0, 1);
CvMat *xyzM = cvCreateMat(24, 3, CV_64F);
cvGEMM(refMacbeth, cmf, k, NULL, 1.0, xyzM, CV_GEMM_A_T);
GShowMat(xyzM, "xyzM", "%8.4f");
SAFE_RELEASEMAT(light);
SAFE_RELEASEMAT(macbeth);
SAFE_RELEASEMAT(cmf);
SAFE_RELEASEMAT(light24);
SAFE_RELEASEMAT(refMacbeth);
SAFE_RELEASEMAT(xyzWhite);
return xyzM;
}
//-------------------------------------------------------------------------------
// 処理画像読み込みと各変換行列の算出
bool CReferenceProc::CalcMatrix(const char *path, const char *file)
{
// 参照画像を開く
char filename[PATH_LEN];
sprintf_s(filename, PATH_LEN, "%s\\%s", path, file);
// マクベスの検出,パッチ色取得
CALL(m_Macbeth->SetImage(filename));
CALL(m_Macbeth->Detect());
CALL(m_Macbeth->CalcPatchColor(&m_crgbRM));
#ifdef SHOW_RGB_VALUES
GShowMat(m_crgbRM, "crgbRM");
#endif // SHOW_RGB_VALUES
// 線形化係数の算出
m_ccmCL->CalcCoef(m_crgbRM);
//m_ccmCL->CalcCurve(); // フィッティングカーブを出力(デバッグ用)
// キャスマッチの検出,パッチ色取得
CALL(m_Casmatch->SetImage(filename));
CALL(m_Casmatch->Detect());
CALL(m_Casmatch->CalcPatchColor9(&m_crgbRC));
#ifdef SHOW_RGB_VALUES
GShowMat(m_crgbRC, "crgbRC");
#endif // SHOW_RGB_VALUES
// パッチ色の線形化
SAFE_RELEASEMAT(m_lrgbRM);
m_lrgbRM = m_ccmCL->GenConvert(m_crgbRM);
SAFE_RELEASEMAT(m_lrgbRC);
m_lrgbRC = m_ccmCL->GenConvert(m_crgbRC);
#ifdef SHOW_RGB_VALUES
GShowMat(m_lrgbRM, "lrgbRM");
GShowMat(m_lrgbRC, "lrgbRC");
#endif // SHOW_RGB_VALUES
// XYZ変換係数の算出
#ifdef SHOW_REGRESSION_COEF
printf("ccmLX ");
#endif // SHOW_REGRESSION_COEF
m_ccmLX->CalcCoef(m_lrgbRM, m_xyzM);
#ifdef SHOW_CV_IMAGE
// 検出結果の描画
IplImage *patched = m_Macbeth->GenPatchedImage();
CALL(m_Casmatch->DrawROI(patched));
GShowImage(patched, 1, "Detection result");
SAFE_RELEASEIMG(patched);
#endif // SHOW_CV_IMAGE
#ifdef SHOW_CALIBRATED_MACBETH
// 色補正結果の表示
IplImage *imgCam = cvLoadImage(filename);
IplImage *imgLin = m_ccmCL->GenConvert(imgCam);
IplImage *imgXYZ = m_ccmLX->GenConvert(imgLin);
IplImage *imgXD = m_ccmXD->GenConvert(imgXYZ);
IplImage *imgDisp = GGenAddGamma(imgXD);
GShowImage(imgDisp, 2, "Calibrated Macbeth");
#endif // SHOW_CALIBRATED_MACBETH
return true;
}
//-------------------------------------------------------------------------------
// 行列データの線形化
CvMat *CReferenceProc::GenLinearize(const CvMat *data)
{
return m_ccmCL->GenConvert(data);
}
//-------------------------------------------------------------------------------
// 画像データの線形化
IplImage *CReferenceProc::GenLinearize(const IplImage *data)
{
return m_ccmCL->GenConvert(data);
}
//-------------------------------------------------------------------------------
// 行列データのXYZ変換
CvMat *CReferenceProc::GenConvertXYZ(const CvMat *data)
{
return m_ccmLX->GenConvert(data);
}
//-------------------------------------------------------------------------------
// 画像データのXYZ変換
IplImage *CReferenceProc::GenConvertXYZ(const IplImage *data)
{
return m_ccmLX->GenConvert(data);
}
//-------------------------------------------------------------------------------
// 行列データのモニター色変換
CvMat *CReferenceProc::GenConvertDisp(const CvMat *data)
{
return m_ccmXD->GenConvert(data);
}
//-------------------------------------------------------------------------------
// 画像データのモニター色変換
IplImage *CReferenceProc::GenConvertDisp(const IplImage *data)
{
return m_ccmXD->GenConvert(data);
}
//-------------------------------------------------------------------------------
// スカラーデータの線形化
CvScalar CReferenceProc::ScalarLinearize(const CvScalar data)
{
return m_ccmCL->ScalarConvert(data);
}
//-------------------------------------------------------------------------------
// スカラーデータのXYZ変換
CvScalar CReferenceProc::ScalarConvertXYZ(const CvScalar data)
{
return m_ccmLX->ScalarConvert(data);
}
//-------------------------------------------------------------------------------
// スカラーデータのモニター色変換
CvScalar CReferenceProc::ScalarConvertDisp(const CvScalar data)
{
return m_ccmXD->ScalarConvert(data);
}