⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calibrat.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/

/*****************************************************
文件说明:校正
版本号:1.0.0
开发时期:1999
作者:ln
修改记录:
******************************************************/


#include <ewindows.h>

#include "largenum.h"
#include "touchcal.h"

#define MAX_POINT_ERROR 5

typedef struct _MATRIX33{
    PLARGENUM   pa11, pa12, pa13;
    PLARGENUM   pa21, pa22, pa23;
    PLARGENUM   pa31, pa32, pa33;
}MATRIX33, *PMATRIX33;

typedef struct _CALIBRATION_PARAMETER{
    int   a1;
    int   b1;
    int   c1;
    int   a2;
    int   b2;
    int   c2;
    int   delta;
}CALIBRATION_PARAMETER, *PCALIBRATION_PARAMETER;

static BOOL bCalibrated = FALSE;
static CALIBRATION_PARAMETER    v_CalcParam = { -21128, 98, 82379318, -614, -26855, 110951931, 132300 };
static void SaveToReg( VOID );

static BOOL
ErrorAnalysis(
    int   cCalibrationPoints,     //
    int   *pScreenXBuffer,        //
    int   *pScreenYBuffer,        //
    int   *pUncalXBuffer,         //
    int   *pUncalYBuffer          //
    );

static VOID
ComputeMatrix33(
    PLARGENUM   pResult,
    PMATRIX33   pMatrix
    );

static VOID
ComputeMatrix33(
    PLARGENUM   pResult,
    PMATRIX33   pMatrix
    )
{
    LARGENUM    lnTemp;

    LargeNumMult(pMatrix->pa11, pMatrix->pa22, &lnTemp);
    LargeNumMult(pMatrix->pa33, &lnTemp, pResult);
    LargeNumMult(pMatrix->pa21, pMatrix->pa32, &lnTemp);
    LargeNumMult(pMatrix->pa13, &lnTemp, &lnTemp);
    LargeNumAdd(pResult, &lnTemp, pResult);
    LargeNumMult(pMatrix->pa12, pMatrix->pa23, &lnTemp);
    LargeNumMult(pMatrix->pa31, &lnTemp, &lnTemp);
    LargeNumAdd(pResult, &lnTemp, pResult);
    LargeNumMult(pMatrix->pa13, pMatrix->pa22, &lnTemp);
    LargeNumMult(pMatrix->pa31, &lnTemp, &lnTemp);
    LargeNumSub(pResult, &lnTemp, pResult);
    LargeNumMult(pMatrix->pa12, pMatrix->pa21, &lnTemp);
    LargeNumMult(pMatrix->pa33, &lnTemp, &lnTemp);
    LargeNumSub(pResult, &lnTemp, pResult);
    LargeNumMult(pMatrix->pa23, pMatrix->pa32, &lnTemp);
    LargeNumMult(pMatrix->pa11, &lnTemp, &lnTemp);
    LargeNumSub(pResult, &lnTemp, pResult);
}

static BOOL
ErrorAnalysis(
    int   cCalibrationPoints,     //
    int   *pScreenXBuffer,        //
    int   *pScreenYBuffer,        //
    int   *pUncalXBuffer,         //
    int   *pUncalYBuffer          //
    )
{
    int     i;
    ULONG maxErr, err;
    int   x,y;
    int   dx,dy;
    UINT  errThreshold = MAX_POINT_ERROR;  // Can be overridden by registry entry
//    UINT  status, ValType, ValLen;
 
    maxErr = 0;
    for(i=0; i<cCalibrationPoints; i++){
        TouchPanelCalibrateAPoint(  
			pUncalXBuffer[i],
			pUncalYBuffer[i],
			&x,
			&y
			);
        x /= 4;
        y /= 4;
		
		dx = x - pScreenXBuffer[i];
        dy = y - pScreenYBuffer[i];
        err = dx * dx + dy * dy;
        if(err > maxErr){
            maxErr = err;
        }
    }
    EdbgOutputDebugString("Maximum error (square of Euclidean distance in screen units) = %u\r\n", maxErr);

    if( maxErr < (errThreshold * errThreshold) ){
       return TRUE;
    } else {
      EdbgOutputDebugString("Maximum error %u exceeds calibration threshold %u\r\n", maxErr, errThreshold);
       return FALSE;
    }
}

//call by calibration ap
BOOL
TouchPanelSetCalibration(
    int   cCalibrationPoints,     //
    int   *pScreenXBuffer,        //
    int   *pScreenYBuffer,        //
    int   *pUncalXBuffer,         //
    int   *pUncalYBuffer          //
    )
{
    LARGENUM    a11;
    LARGENUM    a21, a22;
    LARGENUM    a31, a32, a33;
    LARGENUM    b11, b12, b13;
    LARGENUM    b21, b22, b23;
    LARGENUM    lnScreenX;
    LARGENUM    lnScreenY;
    LARGENUM    lnTouchX;
    LARGENUM    lnTouchY;
    LARGENUM    lnTemp;
    LARGENUM    delta;
    LARGENUM    a1, b1, c1;
    LARGENUM    a2, b2, c2;
    MATRIX33    Matrix;
    int       cShift;
    int       minShift;
    int         i;


    if ( cCalibrationPoints == 0 )
    {
		bCalibrated = FALSE;
        return TRUE;
    }

    LargeNumSet(&a11, 0);
    LargeNumSet(&a21, 0);
    LargeNumSet(&a31, 0);
    LargeNumSet(&a22, 0);
    LargeNumSet(&a32, 0);
    LargeNumSet(&a33, cCalibrationPoints);
    LargeNumSet(&b11, 0);
    LargeNumSet(&b12, 0);
    LargeNumSet(&b13, 0);
    LargeNumSet(&b21, 0);
    LargeNumSet(&b22, 0);
    LargeNumSet(&b23, 0);
    for(i=0; i<cCalibrationPoints; i++){
        LargeNumSet(&lnTouchX, pUncalXBuffer[i]);
        LargeNumSet(&lnTouchY, pUncalYBuffer[i]);
        LargeNumSet(&lnScreenX, pScreenXBuffer[i]);
        LargeNumSet(&lnScreenY, pScreenYBuffer[i]);
        LargeNumMult(&lnTouchX, &lnTouchX, &lnTemp);
        LargeNumAdd(&a11, &lnTemp, &a11);
        LargeNumMult(&lnTouchX, &lnTouchY, &lnTemp);
        LargeNumAdd(&a21, &lnTemp, &a21);
        LargeNumAdd(&a31, &lnTouchX, &a31);
        LargeNumMult(&lnTouchY, &lnTouchY, &lnTemp);
        LargeNumAdd(&a22, &lnTemp, &a22);
        LargeNumAdd(&a32, &lnTouchY, &a32);
        LargeNumMult(&lnTouchX, &lnScreenX, &lnTemp);
        LargeNumAdd(&b11, &lnTemp, &b11);
        LargeNumMult(&lnTouchY, &lnScreenX, &lnTemp);
        LargeNumAdd(&b12, &lnTemp, &b12);
        LargeNumAdd(&b13, &lnScreenX, &b13);
        LargeNumMult(&lnTouchX, &lnScreenY, &lnTemp);
        LargeNumAdd(&b21, &lnTemp, &b21);
        LargeNumMult(&lnTouchY, &lnScreenY, &lnTemp);
        LargeNumAdd(&b22, &lnTemp, &b22);
        LargeNumAdd(&b23, &lnScreenY, &b23);
    }

    Matrix.pa11 = &a11;
    Matrix.pa21 = &a21;
    Matrix.pa31 = &a31;
    Matrix.pa12 = &a21;
    Matrix.pa22 = &a22;
    Matrix.pa32 = &a32;
    Matrix.pa13 = &a31;
    Matrix.pa23 = &a32;
    Matrix.pa33 = &a33;
    ComputeMatrix33(&delta, &Matrix);

    Matrix.pa11 = &b11;
    Matrix.pa21 = &b12;
    Matrix.pa31 = &b13;
    ComputeMatrix33(&a1, &Matrix);

    Matrix.pa11 = &a11;
    Matrix.pa21 = &a21;
    Matrix.pa31 = &a31;
    Matrix.pa12 = &b11;
    Matrix.pa22 = &b12;
    Matrix.pa32 = &b13;
    ComputeMatrix33(&b1, &Matrix);

    Matrix.pa12 = &a21;
    Matrix.pa22 = &a22;
    Matrix.pa32 = &a32;
    Matrix.pa13 = &b11;
    Matrix.pa23 = &b12;
    Matrix.pa33 = &b13;
    ComputeMatrix33(&c1, &Matrix);

    Matrix.pa13 = &a31;
    Matrix.pa23 = &a32;
    Matrix.pa33 = &a33;
    Matrix.pa11 = &b21;
    Matrix.pa21 = &b22;
    Matrix.pa31 = &b23;
    ComputeMatrix33(&a2, &Matrix);

    Matrix.pa11 = &a11;
    Matrix.pa21 = &a21;
    Matrix.pa31 = &a31;
    Matrix.pa12 = &b21;
    Matrix.pa22 = &b22;
    Matrix.pa32 = &b23;
    ComputeMatrix33(&b2, &Matrix);

    Matrix.pa12 = &a21;
    Matrix.pa22 = &a22;
    Matrix.pa32 = &a32;
    Matrix.pa13 = &b21;
    Matrix.pa23 = &b22;
    Matrix.pa33 = &b23;
    ComputeMatrix33(&c2, &Matrix);

    {
        LARGENUM    halfDelta;

        if(IsLargeNumNegative(&delta)){
            LargeNumDivint32(&delta, -2, &halfDelta);
        } else {
            LargeNumDivint32(&delta, 2, &halfDelta);  //
        }
        LargeNumAdd(&c1, &halfDelta, &c1);
        LargeNumAdd(&c2, &halfDelta, &c2);
    }

    //
	minShift = 0;
    cShift = LargeNumBits(&a1) - MAX_COEFF_PRECISION;
    if(cShift > minShift){
        minShift = cShift;
    }
    cShift = LargeNumBits(&b1) - MAX_COEFF_PRECISION;
    if(cShift > minShift){
        minShift = cShift;
    }
    cShift = LargeNumBits(&a2) - MAX_COEFF_PRECISION;
    if(cShift > minShift){
        minShift = cShift;
    }
    cShift = LargeNumBits(&b2) - MAX_COEFF_PRECISION;
    if(cShift > minShift){
        minShift = cShift;
    }
    cShift = LargeNumBits(&c1) - MAX_TERM_PRECISION;
    if(cShift > minShift){
        minShift = cShift;
    }
    cShift = LargeNumBits(&c2) - MAX_TERM_PRECISION;
    if(cShift > minShift){
        minShift = cShift;
    }
    cShift = LargeNumBits(&delta) - 31;
    if(cShift > minShift){
        minShift = cShift;
    }

    //

    if(minShift){
        LargeNumRAShift(&a1, minShift);
        LargeNumRAShift(&a2, minShift);
        LargeNumRAShift(&b1, minShift);
        LargeNumRAShift(&b2, minShift);
        LargeNumRAShift(&c1, minShift);
        LargeNumRAShift(&c2, minShift);
        LargeNumRAShift(&delta, minShift);
    }

    // 校正参数
    v_CalcParam.a1      = a1.u.s32.u[0];
    v_CalcParam.b1      = b1.u.s32.u[0];
    v_CalcParam.c1      = c1.u.s32.u[0];
    v_CalcParam.a2      = a2.u.s32.u[0];
    v_CalcParam.b2      = b2.u.s32.u[0];
    v_CalcParam.c2      = c2.u.s32.u[0];
    v_CalcParam.delta   = delta.u.s32.u[0];

     // 判断delta 是否为零,delta将会成为除数
    if( ! v_CalcParam.delta )
    {
        v_CalcParam.delta = 1;
        bCalibrated = FALSE;
    }
    else
	{
		RETAILMSG( 1, ( "TouchPanelSetCalibration: ok,v_CalcParam(a1=%d,b1=%d,c1=%d,a2=%d,b2=%d,c2=%d,delta=%d).\r\n", v_CalcParam.a1,v_CalcParam.b1,v_CalcParam.c1,v_CalcParam.a2,v_CalcParam.b2,v_CalcParam.c2,v_CalcParam.delta ) );
        bCalibrated = TRUE;
		SaveToReg();
	}

    return ErrorAnalysis(
                    cCalibrationPoints,
                    pScreenXBuffer,
                    pScreenYBuffer,
                    pUncalXBuffer,
                    pUncalYBuffer
                );
}
// call by toucher
void
TouchPanelCalibrateAPoint(
    int   xUnCalibrate,     //原始的x坐标
    int   yUnCalibrate,     //原始的y坐标
    int   *pCalX,     //转换后的x坐标
    int   *pCalY      //转换后的y坐标
    )
{
    int   x, y;

    if ( !bCalibrated ){
        *pCalX = xUnCalibrate;
        *pCalY = yUnCalibrate;
        return;
    }

    //
    // *4 提供附加精度
    //
	x = (v_CalcParam.a1 * xUnCalibrate + v_CalcParam.b1 * yUnCalibrate +
         v_CalcParam.c1) * 4 / v_CalcParam.delta;
    y = (v_CalcParam.a2 * xUnCalibrate + v_CalcParam.b2 * yUnCalibrate +
         v_CalcParam.c2) * 4 / v_CalcParam.delta;
    if ( x < 0 ){
        x = 0;
    }

    if ( y < 0 ){
        y = 0;
    }

    *pCalX = x ;
    *pCalY = y;
}

    
void _InitCalibration( VOID )
{
	HKEY hSubKey;
	DWORD dwType;
	DWORD dwSize;
	char  buf[128+1];

    if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_HARDWARE_ROOT, "DeviceMap\\Touch", 0, KEY_ALL_ACCESS, &hSubKey ) )
	{
		dwSize = sizeof(buf)-1;
		if( ERROR_SUCCESS == RegQueryValueEx( hSubKey, "CalibrationData", NULL, &dwType, buf, &dwSize ) )
		{
			CALIBRATION_PARAMETER cp;
			if( dwSize )
			{
				int n = sizeof(CALIBRATION_PARAMETER) / sizeof(int);
				int i;
				int *lpcp = (int*)&cp;
				char * lp, *lps;
				buf[dwSize] = 0;
				lp = buf;
				for( i = 0; i < n; i++ )
				{
					lps = strchr( lp, ',' );
					if( lps )
					{
						*lps = 0;
						*lpcp++ = atoi( lp );
						lp = lps + 1;
					}
					else
					{	//
						if( i == 6 && *lp )
						{  //最后一个
							*lpcp++ = atoi( lp );
							i++;
						}
						break;
					}
				}
				if( i == n )
				{
					v_CalcParam = cp;
					bCalibrated = TRUE;
					RETAILMSG( 1, ( "_InitCalibration: ok,v_CalcParam(a1=%d,b1=%d,c1=%d,a2=%d,b2=%d,c2=%d,delta=%d).\r\n", v_CalcParam.a1,v_CalcParam.b1,v_CalcParam.c1,v_CalcParam.a2,v_CalcParam.b2,v_CalcParam.c2,v_CalcParam.delta ) );					
				}
			}
		}
		RegCloseKey( hSubKey );
	}
}

void _DeinitCalibration( VOID )
{
}

static VOID SaveToReg( VOID )
{
	HKEY hSubKey;
	DWORD dwType;
	char  buf[128+1];

    //if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_HARDWARE_ROOT, "DeviceMap\\Touch", 0, 0, &hSubKey ) )
    if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_HARDWARE_ROOT, 
										 "DeviceMap\\Touch", 
										 0,
										 0,
										 0,
										 KEY_ALL_ACCESS,
										 NULL,
										 &hSubKey,
										 NULL ) )
	{
		buf[0];
		dwType = REG_SZ;
		sprintf( buf, "%d,%d,%d,%d,%d,%d,%d", v_CalcParam.a1, v_CalcParam.b1, v_CalcParam.c1, v_CalcParam.a2, v_CalcParam.b2, v_CalcParam.c2, v_CalcParam.delta );
		if( ERROR_SUCCESS == RegSetValueEx( hSubKey, "CalibrationData", 0, dwType, buf, strlen(buf) + 1 ) )
		{
		}
		RegCloseKey( hSubKey );
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -