見出し画像

解説クラスCopyClear(23)

解説クラスCopyClear(23)


2025年2月4初稿(初講)

正規化相関関数系の「public:属性」の関数の解説を行います
基本的に画像の比較を行う処理です!
解説『解説クラスCopyClear(22)』の続きです

(4-14-127)関数「void CorrImage44(
TypeArray* pa,
TypeArray* pb,double* buf,
int nStepH,int nStepV,
int& resH,int& resV){・・・}」

/************************************************************************/
/*****      4×4画素正規化相関画像適応                            *****/
/*****      ☆4×4の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::CorrImage44(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                              // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrAY;                                              // A配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅(nStepV単位)
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値
    int         i;                                                  // カウンタ

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 4 || minV < 4 ){                                     // サイズが4×4未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h     = ( minH - 4 ) / nStepH;                                  // 水平個数を算出
    v     = ( minV - 4 ) / nStepV;                                  // 垂直個数を算出
    resH  = h;                                                      // 返値:水平個数
    resV  = v;                                                      // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                         // A配列:処理ポインタ
    ptrBY = (BYTE*)pb->adr;                                         // B配列:処理ポインタ
    incA  = pa->inc * nStepV;                                       // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                                       // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){                // 垂直個数分
        ptrAX = ptrAY;                                              // A配列:水平始点
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH, ptrBX += nStepH ){   // 水平個数分
            *buf++ = Corr44( ptrAX, ptrBX, pa->inc, pb->inc );      // 4×4画素の正規相関を
        }                                                           // 算出しバッファーに格納
    }                                                               //
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「CorrImage44()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します

(B)関数「void CorrImage44()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage44()」の【仮引数】

void            CopyClear::CorrImage44(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「double* buf,」は、結果相関値格納バッファー
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「CorrImage44()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                              // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrAY;                                              // A配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅(nStepV単位)
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値
    int         i;                                                  // カウンタ

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 4 || minV < 4 ){                                     // サイズが4×4未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h     = ( minH - 4 ) / nStepH;                                  // 水平個数を算出
    v     = ( minV - 4 ) / nStepV;                                  // 垂直個数を算出
    resH  = h;                                                      // 返値:水平個数
    resV  = v;                                                      // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                         // A配列:処理ポインタ
    ptrBY = (BYTE*)pb->adr;                                         // B配列:処理ポインタ
    incA  = pa->inc * nStepV;                                       // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                                       // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){                // 垂直個数分
        ptrAX = ptrAY;                                              // A配列:水平始点
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH, ptrBX += nStepH ){   // 水平個数分
            *buf++ = Corr44( ptrAX, ptrBX, pa->inc, pb->inc );      // 4×4画素の正規相関を
        }                                                           // 算出しバッファーに格納
    }                                                               //
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                              // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrAY;                                              // A配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅(nStepV単位)
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値
    int         i;                                                  // カウンタ

「BYTE* ptrAX;」は、A画像用X座標方向処理ポインタ
「BYTE* ptrBX;」は、B画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、A画像用Y座標方向処理ポインタ
「BYTE* ptrBY;」は、B画像用Y座標方向処理ポインタ
「int incA;」は、A画像増加幅
「int incB;」は、B画像増加幅
「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい
「int minH;」は、水平幅の最小値
「int minV;」は、垂直幅の最小値
★備考★上記「int minH;int minV;」は画像自体の
水平垂直幅で、「4×4升枠」を単位とした処理が可能な最小
(有効)画素サイズの算出です!
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 4 || minV < 4 ){                                     // サイズが4×4未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h     = ( minH - 4 ) / nStepH;                                  // 水平個数を算出
    v     = ( minV - 4 ) / nStepV;                                  // 垂直個数を算出
    resH  = h;                                                      // 返値:水平個数
    resV  = v;                                                      // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                         // A配列:処理ポインタ
    ptrBY = (BYTE*)pb->adr;                                         // B配列:処理ポインタ
    incA  = pa->inc * nStepV;                                       // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                                       // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){                // 垂直個数分
        ptrAX = ptrAY;                                              // A配列:水平始点
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH, ptrBX += nStepH ){   // 水平個数分
            *buf++ = Corr44( ptrAX, ptrBX, pa->inc, pb->inc );      // 4×4画素の正規相関を
        }                                                           // 算出しバッファーに格納
    }                                                               //
}

「minH=((pa->h<pb->h)?pa->h:pb->h);」は、水平画素数の
有効(最小)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v);」は、垂直画素数の
有効(最小)サイズ算出!
「if(minH<4||minV<4){resH=0;resV=0;return;}」は、if
条件「minH<4||minV<4」有効サイズが「4×4」升枠が、
出来無いで「resH=0;resV=0;return;」と水平垂直の処理個
数が0に仮引数辺値にセットし、関数終了!
「h=(minH-4)/nStepH;v=(minV-4)/nStepV;resH=h;resV=v;」
は、「4×4」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;ptrBY=(BYTE*)pb->adr;」は、処理
し易い様にY座標方向始点をポインタ変数にセット!
「incA=pa->incnStepV;incB=pb->incnStepV;」は、画素
単位の「4×4」升枠でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA,ptrBY+=incB){・・外側ループ
本体・・}」は、ループ条件「--v>=0;」と良くこの解説で
説明して居る≪「--v」と値が変っても良い変数をダウンカ
ウンタに使用する事で教科書的な記述よりも現実のコンパイ
ラ環境で依り高速な機械コード(アセンブラ出力で確認)が
生成されるので私のソースコードでは多く採用≫とループ
本体終了後の処理「ptrAY+=incA,ptrBY+=incB」が、次の
X座標方向始点へ渡す為のY座標方向ポインタを垂直方向に
増加している!そして外側ループ本体
「ptrAX=ptrAY;ptrBX=ptrBY;」は、X座標方向始点を
ポインタ変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH,ptrBX+=nStepH){・・内側
ループ本体・・}」は、for構文の初期化「i=h;」で
ループカウンタ「i」をダウンカウンタとしセットし、ルー
プ条件「--i>=0;」と良くこの解説で説明して居る≪「--i」
と値が変っても良い変数をダウンカウンタに使用する事で
教科書的な記述よりも現実のコンパイラ環境で依り高速な
機械コード(アセンブラ出力で確認)が生成されるので私の
ソースコードでは多く採用≫とループ本体終了後の処理
「ptrAX+=nStepH,ptrBX+=nStepH」が、X座標方向ポインタ
を水平方向に増加している!そして内側ループ本体
「*buf++=Corr44(ptrAX,ptrBX,pa->inc,pb->inc);」は、
サブルーチン関数「Corr44()」で「4×4」升枠で相関値を
算出し「*buf++=・・」とバッファーに追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-128)関数「void GetHVCorrImage44(
TypeArray* pa,
TypeArray* pb,int nStepH,
int nStepV,int& resH,int& resV){・・・}」

/************************************************************************/
/*****      4×4画素正規化相関画像適応用升目の個数取得            *****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::GetHVCorrImage44(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 4 || minV < 4 ){                                     // サイズが4×4未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( minH - 4 ) / nStepH;                                   // 水平個数を算出
    v    = ( minV - 4 ) / nStepV;                                   // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「GetHVCorrImage44()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対してを算出する関数「CorrImage44()」を意味≫し、
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します!
この関数「GetHVCorrImage44()」は、その補助関数として
関数「CorrImage44()」の前に仮引数「int &resH,
int &resV」で水平垂直方向の結果個数を事前算出する事を
行います!

(B)関数「void GetHVCorrImage44()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVCorrImage44()」の【仮引数】

void            CopyClear::GetHVCorrImage44(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「GetHVCorrImage44()」の【アルゴリズム】

){
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 4 || minV < 4 ){                                     // サイズが4×4未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( minH - 4 ) / nStepH;                                   // 水平個数を算出
    v    = ( minV - 4 ) / nStepV;                                   // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

(D-1)ローカル変数

){
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値

「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい
「int minH;」は、水平幅の最小値
「int minV;」は、垂直幅の最小値
★備考★上記「int minH;int minV;」は画像自体の
水平垂直幅で、「4×4升枠」を単位とした処理が可能な最小
(有効)画素サイズの算出です!

(D-2)アルゴリズムコード

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 4 || minV < 4 ){                                     // サイズが4×4未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( minH - 4 ) / nStepH;                                   // 水平個数を算出
    v    = ( minV - 4 ) / nStepV;                                   // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

「minH=((pa->h<pb->h)?pa->h:pb->h);」は、水平画素数の
有効(最小)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v);」は、垂直画素数の
有効(最小)サイズ算出!
「if(minH<4||minV<4){resH=0;resV=0;return;}」は、if
条件「minH<4||minV<4」有効サイズが「4×4」升枠が、
出来無いで「resH=0;resV=0;return;」と水平垂直の処理個
数が0に仮引数辺値にセットし、関数終了!
「h=(minH-4)/nStepH;v=(minV-4)/nStepV;resH=h;resV=v;」
は、「4×4」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
★備考★関数「CorrImage44()」で仮引数「double* buf,」
とバッファーを動的に必要なサイズ用意する必要が有るの
で、この関数で仮引数「int &resH,int &resV」で水平垂直
方向の結果個数を算出する事で用意しする事にしています!

(4-14-129)関数「void AverageImage44(
TypeArray* pa,
BYTE* buf,int nStepH,
int nStepV,int& resH,int& resV){・・・}」

/************************************************************************/
/*****      4×4画素画像平均適応                                  *****/
/*****      ☆4×4の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::AverageImage44(
    TypeArray*  pa,                                         // A配列
    BYTE*       buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = (int)Ave4M( ptrAX, pa->inc, 4 );       // 4×4画素平均算出
        }                                                   //
    }                                                       //
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage44()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「44」は、処理する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します

(B)関数「void AverageImage44()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「AverageImage44()」の【仮引数】

void            CopyClear::AverageImage44(
    TypeArray*  pa,                                         // A配列
    BYTE*       buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「BYTE* buf,」は、平均値格納バッファー
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「AverageImage44()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = (int)Ave4M( ptrAX, pa->inc, 4 );       // 4×4画素平均算出
        }                                                   //
    }                                                       //
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

「BYTE* ptrAX;」は、画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、画像用Y座標方向処理ポインタ
「int incA;」は、画像増加幅
「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = (int)Ave4M( ptrAX, pa->inc, 4 );       // 4×4画素平均算出
        }                                                   //
    }                                                       //
}

「if(pa->h<4||pa->v<4){resH=0;resV=0;return;}」は、
if条件「pa->h<4||pa->v<4」有効サイズが「4×4」升枠
が、出来無いで「resH=0;resV=0;return;」と
水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!
「h=(pa->h-4)/nStepH;v=(pa->v-4)/nStepV;」
は、「4×4」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;」は、処理し易い様にY座標方向
始点をポインタ変数にセット!
「incA=pa->inc*nStepV;」は、画素単位の「4×4」升枠
でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA){・・外側ループ本体・・}」は
ループ条件「--v>=0;」と良くこの解説で説明して居る≪
「--v」と値が変っても良い変数をダウンカウンタに使用
する事で教科書的な記述よりも現実のコンパイラ環境で依り
高速な機械コード(アセンブラ出力で確認)が生成されるの
で私のソースコードでは多く採用≫とループ本体終了後の
処理「ptrAY+=incA」が、次のX座標方向始点へ渡す為の
Y座標方向ポインタを垂直方向に増加している!そして外側
ループ本体「ptrAX=ptrAY;」は、X座標方向始点をポインタ
変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH){・・内側ループ本体・・
}」は、for構文の初期化「i=h;」でループカウンタ「i」
をダウンカウンタとしセットし、ループ条件「--i>=0;」と
良くこの解説で説明して居る≪「--i」と値が変っても良い
変数をダウンカウンタに使用する事で教科書的な記述よりも
現実のコンパイラ環境で依り高速な機械コード(アセンブラ
出力で確認)が生成されるので私のソースコードでは多く
採用≫とループ本体終了後の処理「ptrAX+=nStepH」が、
X座標方向ポインタを水平方向に増加している!そして内側
ループ本体
「*buf++=(int)Ave4M(ptrAX,pa->inc,4);」は、サブルーチ
ン関数「Ave4M(・・,4)」で「4×4」升枠で平均値を算出
し「*buf++=・・」とバッファーに「(int)」と整数型に
型変換≪小数点以下は切り捨て≫追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-130)関数「void AverageImage44(
TypeArray* pa,double* buf,
int nStepH,int nStepV,
int& resH,int& resV){・・・}」

/************************************************************************/
/*****      4×4画素画像平均適応                                  *****/
/*****      ☆4×4の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::AverageImage44(
    TypeArray*  pa,                                         // A配列
    double*     buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Ave4M( ptrAX, pa->inc, 4 );            // 4×4画素平均算出
        }                                                   //
    }                                                       //
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage44()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「44」は、処理する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します

(B)関数「void AverageImage44()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「AverageImage44()」の【仮引数】

void            CopyClear::AverageImage44(
    TypeArray*  pa,                                         // A配列
    double*     buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「double* buf,」は、平均値格納バッファー
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「AverageImage44()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Ave4M( ptrAX, pa->inc, 4 );            // 4×4画素平均算出
        }                                                   //
    }                                                       //
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

「BYTE* ptrAX;」は、画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、画像用Y座標方向処理ポインタ
「int incA;」は、画像増加幅
「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Ave4M( ptrAX, pa->inc, 4 );            // 4×4画素平均算出
        }                                                   //
    }                                                       //
}

「if(pa->h<4||pa->v<4){resH=0;resV=0;return;}」は、
if条件「pa->h<4||pa->v<4」有効サイズが「4×4」升枠
が、出来無いで「resH=0;resV=0;return;」と
水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!
「h=(pa->h-4)/nStepH;v=(pa->v-4)/nStepV;」
は、「4×4」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;」は、処理し易い様にY座標方向
始点をポインタ変数にセット!
「incA=pa->inc*nStepV;」は、画素単位の「4×4」升枠
でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA){・・外側ループ本体・・}」は
ループ条件「--v>=0;」と良くこの解説で説明して居る≪
「--v」と値が変っても良い変数をダウンカウンタに使用
する事で教科書的な記述よりも現実のコンパイラ環境で依り
高速な機械コード(アセンブラ出力で確認)が生成されるの
で私のソースコードでは多く採用≫とループ本体終了後の
処理「ptrAY+=incA」が、次のX座標方向始点へ渡す為の
Y座標方向ポインタを垂直方向に増加している!そして外側
ループ本体「ptrAX=ptrAY;」は、X座標方向始点をポインタ
変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH){・・内側ループ本体・・
}」は、for構文の初期化「i=h;」でループカウンタ「i」
をダウンカウンタとしセットし、ループ条件「--i>=0;」と
良くこの解説で説明して居る≪「--i」と値が変っても良い
変数をダウンカウンタに使用する事で教科書的な記述よりも
現実のコンパイラ環境で依り高速な機械コード(アセンブラ
出力で確認)が生成されるので私のソースコードでは多く
採用≫とループ本体終了後の処理「ptrAX+=nStepH」が、
X座標方向ポインタを水平方向に増加している!そして内側
ループ本体
「*buf++=Ave4M(ptrAX,pa->inc,4);」は、サブルーチン関数
「Ave4M(・・,4)」で「4×4」升枠で平均値を算出し
「*buf++=・・」とバッファーに追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-131)関数「void CorrImage44Myself(
TypeArray* pa,int* buf,
int nStepH,int nStepV,int &resH,int &resV){・・・}」

/************************************************************************/
/*****      4×4画素自己相関画像適応                              *****/
/*****      ☆4×4の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::CorrImage44Myself(
    TypeArray*  pa,                                         // A配列
    int*        buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Corr44Myself( ptrAX, pa->inc );        // 4×4画素自己相関算出
        }                                                   //
    }                                                       //
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44Myself()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を整数型で算出しますのでモット大きな整数値に成ります!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!

(B)関数「void CorrImage44Myself()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage44Myself()」の【仮引数】

void            CopyClear::CorrImage44Myself(
    TypeArray*  pa,                                         // A配列
    int*        buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「int* buf,」は、自己相関値格納バッファー
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「CorrImage44Myself()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Corr44Myself( ptrAX, pa->inc );        // 4×4画素自己相関算出
        }                                                   //
    }                                                       //
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)
    int         i;                                          // カウンタ

「BYTE* ptrAX;」は、画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、画像用Y座標方向処理ポインタ
「int incA;」は、画像増加幅
「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 4 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 4 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Corr44Myself( ptrAX, pa->inc );        // 4×4画素自己相関算出
        }                                                   //
    }                                                       //
}

「if(pa->h<4||pa->v<4){resH=0;resV=0;return;}」は、
if条件「pa->h<4||pa->v<4」有効サイズが「4×4」升枠
が、出来無いで「resH=0;resV=0;return;resH=h;resV=v;」と
水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!
「h=(pa->h-4)/nStepH;v=(pa->v-4)/nStepV;」
は、「4×4」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;」は、処理し易い様にY座標方向
始点をポインタ変数にセット!
「incA=pa->inc*nStepV;」は、画素単位の「4×4」升枠
でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA){・・外側ループ本体・・}」は
ループ条件「--v>=0;」と良くこの解説で説明して居る≪
「--v」と値が変っても良い変数をダウンカウンタに使用
する事で教科書的な記述よりも現実のコンパイラ環境で依り
高速な機械コード(アセンブラ出力で確認)が生成されるの
で私のソースコードでは多く採用≫とループ本体終了後の
処理「ptrAY+=incA」が、次のX座標方向始点へ渡す為の
Y座標方向ポインタを垂直方向に増加している!そして外側
ループ本体「ptrAX=ptrAY;」は、X座標方向始点をポインタ
変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH){・・内側ループ本体・・
}」は、for構文の初期化「i=h;」でループカウンタ「i」
をダウンカウンタとしセットし、ループ条件「--i>=0;」と
良くこの解説で説明して居る≪「--i」と値が変っても良い
変数をダウンカウンタに使用する事で教科書的な記述よりも
現実のコンパイラ環境で依り高速な機械コード(アセンブラ
出力で確認)が生成されるので私のソースコードでは多く
採用≫とループ本体終了後の処理「ptrAX+=nStepH」が、
X座標方向ポインタを水平方向に増加している!そして内側
ループ本体
「*buf++=Corr44Myself(ptrAX,pa->inc);」は、サブルー
チン関数「Corr44Myself()」で「4×4」升枠で分散値を
算出し「*buf++=・・」とバッファーに追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-132)関数「void GetHVCorrImage44Myself(
TypeArray* pa,int nStepH,
int nStepV,int &resH,int &resV){・・・}」

/************************************************************************/
/*****      4×4画素自己相関画像適応用升目の個数取得              *****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::GetHVCorrImage44Myself(
    TypeArray*  pa,                                         // A配列
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h    = ( pa->h - 4 ) / nStepH;                          // 水平個数を算出
    v    = ( pa->v - 4 ) / nStepV;                          // 垂直個数を算出
    resH = h;                                               // 返値:水平個数
    resV = v;                                               // 返値:垂直個数
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「GetHVCorrImage44Myself()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
ここは、自己相関の補助関数として「int* buf,」を
多重定義(オーバーロード)関数から外す事で自己相関を
算出で無く、仮引数「int &resH,int &resV」の値を算出
する事で事前にバッファー取得の予備に使用します!

(B)関数「void GetHVCorrImage44Myself()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVCorrImage44Myself()」の【仮引数】

void            CopyClear::GetHVCorrImage44Myself(
    TypeArray*  pa,                                         // A配列
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「GetHVCorrImage44Myself()」の【アルゴリズム】

){
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h    = ( pa->h - 4 ) / nStepH;                          // 水平個数を算出
    v    = ( pa->v - 4 ) / nStepV;                          // 垂直個数を算出
    resH = h;                                               // 返値:水平個数
    resV = v;                                               // 返値:垂直個数
}

(D-1)ローカル変数

){
    int         h;                                          // 水平幅(4×4の個数)
    int         v;                                          // 垂直幅(4×4の個数)

「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい

(D-2)アルゴリズムコード

    if( pa->h < 4 || pa->v < 4 ){                           // サイズが4×4未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h    = ( pa->h - 4 ) / nStepH;                          // 水平個数を算出
    v    = ( pa->v - 4 ) / nStepV;                          // 垂直個数を算出
    resH = h;                                               // 返値:水平個数
    resV = v;                                               // 返値:垂直個数
}

「if(pa->h<4||pa->v<4){resH=0;resV=0;return;}」は、
if条件「pa->h<4||pa->v<4」有効サイズが「4×4」升枠
が、出来無いで「resH=0;resV=0;return;」と
水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!
「h=(pa->h-4)/nStepH;v=(pa->v-4)/nStepV;」
は、「4×4」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!

(4-14-133)関数「void SearchCorrImage44(
TypeArray* pa,
TypeArray* pb,double* buf,
int nStepH,int nStepV,int &resH,int &resV){・・・}

/****************************************************************************/
/*****      4×4画素正規化相関サーチ画像適応                          *****/
/*****      ☆4×4の基本単位毎に画像をサーチし結果をバッファーに格納☆*****/
/*****      引数返値:水平個数                                          *****/
/*****      引数返値:垂直個数                                          *****/
/****************************************************************************/

void            CopyClear::SearchCorrImage44(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         sumA;                                               // 合計A(及び自己相関)
    int         avA;                                                // 平均A
    int         avB;                                                // 平均B
    int         i;                                                  // カウンタ
    int         j;                                                  // カウンタ

    if( pa->h < 4 || pa->v < 4 || pb->h < 4 || pb->v < 4 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h      = ( pb->h - 4 ) / nStepH;                                // 水平個数を算出
    v      = ( pb->v - 4 ) / nStepV;                                // 垂直個数を算出
    resH   = h;                                                     // 返値:水平個数
    resV   = v;                                                     // 返値:垂直個数
    ptrA   = (BYTE*)pa->adr;                                        // A配列:処理ポインタ
    ptrBY  = (BYTE*)pb->adr;                                        // B配列:処理ポインタ
    incB   = pb->inc * nStepV;                                      // B配列:増加幅(nStepV単位)
    *buf++ = Corr44First( ptrA, ptrBY, pa->inc, pb->inc,            // 先頭の時の相関値算出
                                                avA, avB, sumA );   //
    for( i = 0; i < v; i++, ptrBY += incB ){                        // 垂直個数分
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( j = 0; j < h; j++, ptrBX += nStepH ){                  // 水平個数分
            if( !( i == 0 && j == 0 ) ){                            // 先頭以外ならば
                *buf++ = Corr44Second( ptrA, ptrBX,                 // 4×4画素の正規相関を
                                pa->inc, pb->inc, avA, avB, sumA ); // 算出しバッファーに格納
            }                                                       //
        }                                                           //
    }                                                               //
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「SearchCorrImage44()」の【関数名】

「Search」は、英単語「Search」で「探す・探索」です!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します!

(B)関数「void SearchCorrImage44()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「SearchCorrImage44()」の【仮引数】

void            CopyClear::SearchCorrImage44(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A≪テンプレート画像≫
「TypeArray* pb,」は、比較対象画像B≪サーチ対象画像≫
「double* buf,」は、結果相関値格納バッファー
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「SearchCorrImage44()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         sumA;                                               // 合計A(及び自己相関)
    int         avA;                                                // 平均A
    int         avB;                                                // 平均B
    int         i;                                                  // カウンタ
    int         j;                                                  // カウンタ

    if( pa->h < 4 || pa->v < 4 || pb->h < 4 || pb->v < 4 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h      = ( pb->h - 4 ) / nStepH;                                // 水平個数を算出
    v      = ( pb->v - 4 ) / nStepV;                                // 垂直個数を算出
    resH   = h;                                                     // 返値:水平個数
    resV   = v;                                                     // 返値:垂直個数
    ptrA   = (BYTE*)pa->adr;                                        // A配列:処理ポインタ
    ptrBY  = (BYTE*)pb->adr;                                        // B配列:処理ポインタ
    incB   = pb->inc * nStepV;                                      // B配列:増加幅(nStepV単位)
    *buf++ = Corr44First( ptrA, ptrBY, pa->inc, pb->inc,            // 先頭の時の相関値算出
                                                avA, avB, sumA );   //
    for( i = 0; i < v; i++, ptrBY += incB ){                        // 垂直個数分
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( j = 0; j < h; j++, ptrBX += nStepH ){                  // 水平個数分
            if( !( i == 0 && j == 0 ) ){                            // 先頭以外ならば
                *buf++ = Corr44Second( ptrA, ptrBX,                 // 4×4画素の正規相関を
                                pa->inc, pb->inc, avA, avB, sumA ); // 算出しバッファーに格納
            }                                                       //
        }                                                           //
    }                                                               //
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)
    int         sumA;                                               // 合計A(及び自己相関)
    int         avA;                                                // 平均A
    int         avB;                                                // 平均B
    int         i;                                                  // カウンタ
    int         j;                                                  // カウンタ

「BYTE* ptrAX;」は、A画像用X座標方向処理ポインタ
「BYTE* ptrBX;」は、B画像用X座標方向処理ポインタ
「BYTE* ptrBY;」は、B画像用Y座標方向処理ポインタ
「int incB;」は、B画像増加幅
「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい
「int sumA;」は、A画像用合計値、及び分散値算出用
「int avA;」は、A画像平均値
「int avB;」は、B画像平均値
「int i;」は、ループカウンタ外側
「int j;」は、ループカウンタ内側

(D-2)アルゴリズムコード

    if( pa->h < 4 || pa->v < 4 || pb->h < 4 || pb->v < 4 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h      = ( pb->h - 4 ) / nStepH;                                // 水平個数を算出
    v      = ( pb->v - 4 ) / nStepV;                                // 垂直個数を算出
    resH   = h;                                                     // 返値:水平個数
    resV   = v;                                                     // 返値:垂直個数
    ptrA   = (BYTE*)pa->adr;                                        // A配列:処理ポインタ
    ptrBY  = (BYTE*)pb->adr;                                        // B配列:処理ポインタ
    incB   = pb->inc * nStepV;                                      // B配列:増加幅(nStepV単位)
    *buf++ = Corr44First( ptrA, ptrBY, pa->inc, pb->inc,            // 先頭の時の相関値算出
                                                avA, avB, sumA );   //
    for( i = 0; i < v; i++, ptrBY += incB ){                        // 垂直個数分
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( j = 0; j < h; j++, ptrBX += nStepH ){                  // 水平個数分
            if( !( i == 0 && j == 0 ) ){                            // 先頭以外ならば
                *buf++ = Corr44Second( ptrA, ptrBX,                 // 4×4画素の正規相関を
                                pa->inc, pb->inc, avA, avB, sumA ); // 算出しバッファーに格納
            }                                                       //
        }                                                           //
    }                                                               //
}

「if(pa->h<4||pa->v<4||pb->h<4||pb->v<4){
resH=0;resV=0;return;}」は、if条件
「pa->h<4||pa->v<4||pb->h<4||pb->v<4」有効サイズが
「4×4」升枠が、出来無いで「resH=0;resV=0;return;」
と水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!は、
「h=(pb->h-4)/nStepH;v=(pb->v-4)/nStepV;」は、水平垂直
の処理升の個数を算出!
「resH=h;resV=v;」は、仮引数「int &resH,int &resV」に
引数辺値とし格納!
「ptrA=(BYTE*)pa->adr;ptrBY=(BYTE*)pb->adr;」は、処理
し易い様にA画像用X座標方向とY座標方向始点をポインタ
変数にセット!
「incB=pb->inc*nStepV;」は、画素単位の「4×4」升枠で
のポインタ増加幅を算出しセット!
「*buf++=Corr44First(ptrA,ptrBY,pa->inc,pb->inc,avA,
avB,sumA);」は、サブルーチン関数「Corr44First()」で
最初の「4×4」升枠の処理を行います!
次は、処理する二重ループで
「for(i=0;i<v;i++,ptrBY+=incB){・・外側ループ本体・・}
」は、ループ初期値「i=0;」ループ条件「i<v;」ループ終了
後処理「i++,ptrBY+=incB」と教科書的for構文でのアッ
プカウンタ「i=0;」を条件「i<v;」増分「i++,」と「0から
v未満」まで繰り返し同時に「ptrBY+=incB」と垂直方向に
ポインタ増加で外側ループ本体で
「ptrBX=ptrBY;」は、B画像用X座標方向処理ポインタを
セットし、内側ループ「for(j=0;j<h;j++,ptrBX+=nStepH){
・・内側ループ本体・・}」とし繰り返します!そのfor
構文「for(j=0;j<h;j++,ptrBX+=nStepH)」は、ループ初期
値「j=0;」ループ条件「j<h;」ループ終了後処理
「j++,ptrBX+=nStepH」と教科書的for構文でのアップカ
ウンタ「j=0;」を条件「j<h;」増分「j++,」と「0から
h未満」まで繰り返し同時に「ptrBX+=nStepH」と水平方向に
ポインタ増加でif構文「if(!(i==0&&j==0)){
*buf++=Corr44Second(ptrA,ptrBX,pa->inc,pb->inc,avA,
avB,sumA);}」とif条件「!(i==0&&j==0)」詰り、ループカ
ウンタ「i,j」が同時に「0」最初以外で成立中身「*buf++=
Corr44Second(ptrA,ptrBX,pa->inc,pb->inc,avA,avB,sumA);
」とサブルーチン関数「Corr44Second()」で処理します!
★備考★最初の処理が、サブルーチン関数「Corr44First()
」で専用の処理を行うので関数名「Corr44First」に
「First」を明示し、それ以外を通常処理として行うので
関数名「Corr44Second」と「Second」を明示しました!
コノ「First」・「Second」は、他の関数でも同じ様な関係
で使用しますので注意して下さい!

(4-14-134)関数「void GetHVSearchCorrImage44(
TypeArray* pa,
TypeArray* pb,
int nStepH,int nStepV,
int &resH,int &resV){・・・}

/************************************************************************/
/*****      4×4画素正規化相関サーチ画像適応用升目の個数取得      *****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::GetHVSearchCorrImage44(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)

    if( pa->h < 4 || pa->v < 4 || pb->h < 4 || pb->v < 4 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( pb->h - 4 ) / nStepH;                                  // 水平個数を算出
    v    = ( pb->v - 4 ) / nStepV;                                  // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「GetHVSearchCorrImage44()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Search」は、英単語「Search」で「探す・探索」です!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
ここは、画像サーチの補助関数として「double* buf,」を
算出で無く、仮引数「int &resH,int &resV」の値を算出
する事で事前にバッファー取得の予備に使用します!

(B)関数「void GetHVSearchCorrImage44()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVSearchCorrImage44()」の【仮引数】

void            CopyClear::GetHVSearchCorrImage44(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A≪テンプレート画像≫
「TypeArray* pb,」は、比較対象画像B≪サーチ対象画像≫
「int nStepH,」は、比較4×4升枠移動水平方向ステップ
「int nStepV,」は、比較4×4升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「GetHVSearchCorrImage44()」の【アルゴリズム】

){
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)

    if( pa->h < 4 || pa->v < 4 || pb->h < 4 || pb->v < 4 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( pb->h - 4 ) / nStepH;                                  // 水平個数を算出
    v    = ( pb->v - 4 ) / nStepV;                                  // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

(D-1)ローカル変数

){
    int         h;                                                  // 水平幅(4×4の個数)
    int         v;                                                  // 垂直幅(4×4の個数)

「int h;」は、水平幅(4×4の個数)
「int v;」は、垂直幅(4×4の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「4×4升枠」を単位とした処理個数に注意して下さい

(D-2)アルゴリズムコード

    if( pa->h < 4 || pa->v < 4 || pb->h < 4 || pb->v < 4 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( pb->h - 4 ) / nStepH;                                  // 水平個数を算出
    v    = ( pb->v - 4 ) / nStepV;                                  // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

「if(pa->h<4||pa->v<4||pb->h<4||pb->v<4){
resH=0;resV=0;return;}」は、if条件
「pa->h<4||pa->v<4||pb->h<4||pb->v<4」有効サイズが
「4×4」升枠が、出来無いで「resH=0;resV=0;return;」
と水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!は、
「h=(pb->h-4)/nStepH;v=(pb->v-4)/nStepV;」は、水平垂直
の処理升の個数を算出!
「resH=h;resV=v;」は、仮引数「int &resH,int &resV」に
引数辺値とし格納!

(4-14-135)関数「double AverageImage44XY(
TypeArray* pa,int x,int y){・・・}

/************************************************************************************/
/*****      4×4画素画像平均適応:個別                                        *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

double          CopyClear::AverageImage44XY(
    TypeArray*  pa,                                                 // A配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Ave4M( ptrA + x + y * incA, incA, 4 ) );            // 4×4画素平均算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage44XY()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「44」は、処理する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の平均値算出関数です!

(B)関数「double AverageImage44XY()」の【返値】

関数返値として算出した平均値を返す関数です!

(C)関数「AverageImage44XY()」の【仮引数】

double          CopyClear::AverageImage44XY(
    TypeArray*  pa,                                                 // A配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){

「TypeArray* pa,」は、画像情報
「int x」は、X座標
「int y」は、Y座標

(D)関数「AverageImage44XY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Ave4M( ptrA + x + y * incA, incA, 4 ) );            // 4×4画素平均算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

「BYTE* ptrA;」は、画素単位処理ポインタ
「int incA;」は、増加幅★備考★「int inc;」の方が相応
しいと思われるでしょう、この記載に成ったのは、単に
コピペで他の部分から流用したからです!同じ様に処理ポイ
ンタも「BYTE* ptr;」の方が相応しいが、同じ理由から、
この変数名に成ったのです!
「int minH;」は、水平幅の有効(4×4升枠を考慮)幅
「int minV;」は、垂直幅の有効(4×4升枠を考慮)幅

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Ave4M( ptrA + x + y * incA, incA, 4 ) );            // 4×4画素平均算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

「minH=pa->h-4;」は、水平有効幅算出
「minV=pa->v-4;」は、垂直有効幅算出
「ptrA=(BYTE*)pa->adr;」は、処理ポインタのセット
「incA=pa->inc;」は、増加幅のセット
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立中身・・}」
は、条件「x>=0&&x<minH&&y>=0&&y<minV」で有効サイズで
「4×4」升枠が、XY座標設定時に有効な場合、成立
「return(Ave4M(ptrA+x+yincA,incA,4));」とサブルーチ
ン関数「Ave4M(ptrA+x+yincA,incA,4));」で処理し関数
終了!
不成立「else{return(0.0);}」で関数辺値として「0.0」を
返し関数終了!

(4-14-136)関数「void AverageImage44XY(
TypeArray* pa,TypeXY* xy,
BYTE* buf,int size,int offX=0,
int offY=0){・・・}

/************************************************************************************/
/*****      4×4画素画像平均適応                                              *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

void            CopyClear::AverageImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    BYTE*       buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = (int)Ave4M( ptrA + x + y * incA, incA, 4 );      // 4×4画素平均算出
        }else{                                                      // 範囲外ならば
            *buf = 0;                                               // 0をセット
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage44XY()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「44」は、処理する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の平均値算出関数です!
この多重定義(オーバーロード)関数は、
仮引数「TypeXY* xy,」で複数指定します!

(B)関数「void AverageImage44XY()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「AverageImage44XY()」の【仮引数】

void            CopyClear::AverageImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    BYTE*       buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){

「TypeArray* pa,」は、画像情報
「TypeXY* xy,」は、XY座標バッファーで複数指定!
「BYTE* buf,」は、結果格納バッファー!
「int size,」は、XY座標バッファー及び結果バッファー
のサイズです!
「int offX,」は、画像始点からのオフセット座標のX座標
「int offY 」は、画像始点からのオフセット座標のY座標

(D)関数「AverageImage44XY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = (int)Ave4M( ptrA + x + y * incA, incA, 4 );      // 4×4画素平均算出
        }else{                                                      // 範囲外ならば
            *buf = 0;                                               // 0をセット
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

「BYTE* ptrA;」は、画素単位処理ポインタ
「int incA;」は、増加幅★備考★「int inc;」の方が相応
しいと思われるでしょう、この記載に成ったのは、単に
コピペで他の部分から流用したからです!同じ様に処理ポイ
ンタも「BYTE* ptr;」の方が相応しいが、同じ理由から、
この変数名に成ったのです!
「int minH;」は、水平幅の有効(4×4升枠を考慮)幅
「int minV;」は、垂直幅の有効(4×4升枠を考慮)幅
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = (int)Ave4M( ptrA + x + y * incA, incA, 4 );      // 4×4画素平均算出
        }else{                                                      // 範囲外ならば
            *buf = 0;                                               // 0をセット
        }                                                           // 
    }                                                               // 
}

「minH=pa->h-4;」は、水平有効幅算出
「minV=pa->v-4;」は、垂直有効幅算出
「ptrA=(BYTE*)pa->adr;」は、処理ポインタのセット
「incA=pa->inc;」は、増加幅のセット
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は仮引数「TypeXY* xy,」
からXY座標を取り出す!
「if(x>=0&&x<minH&&y>=0&&y<minV){
buf=(int)Ave4M(ptrA+x+yincA,incA,4);}」は、if条件
「x>=0&&x<minH&&y>=0&&y<minV」で取り出したXY座標が、
有効な時「buf=(int)Ave4M(ptrA+x+yincA,incA,4);」と
サブルーチン関数「Ave4M(ptrA+x+y*incA,incA,4);」で
平均値算出し、「*buf=(int)・・・」は、整数型に型変換(
小数点以下切り捨て)し結果バッファに格納!
「else{*buf=0;}」は、XY座標が範囲外の場合で
「*buf=0;」とバッファに「0」を格納!

(4-14-137)関数「void AverageImage44XY(
TypeArray* pa,TypeXY* xy,
double* buf,int size,int offX=0,
int offY=0){・・・}

/************************************************************************************/
/*****      4×4画素画像平均適応                                              *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

void            CopyClear::AverageImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Ave4M( ptrA + x + y * incA, incA, 4 );           // 4×4画素平均算出
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage44XY()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「44」は、処理する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の平均値算出関数です!
この多重定義(オーバーロード)関数は、
仮引数「TypeXY* xy,」で複数指定します!

(B)関数「void AverageImage44XY()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「AverageImage44XY()」の【仮引数】

void            CopyClear::AverageImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){

「TypeArray* pa,」は、画像情報
「TypeXY* xy,」は、XY座標バッファーで複数指定!
「double* buf,」は、結果格納バッファー!
「int size,」は、XY座標バッファー及び結果バッファー
のサイズです!
「int offX,」は、画像始点からのオフセット座標のX座標
「int offY 」は、画像始点からのオフセット座標のY座標

(D)関数「AverageImage44XY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Ave4M( ptrA + x + y * incA, incA, 4 );           // 4×4画素平均算出
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

「BYTE* ptrA;」は、画素単位処理ポインタ
「int incA;」は、増加幅★備考★「int inc;」の方が相応
しいと思われるでしょう、この記載に成ったのは、単に
コピペで他の部分から流用したからです!同じ様に処理ポイ
ンタも「BYTE* ptr;」の方が相応しいが、同じ理由から、
この変数名に成ったのです!
「int minH;」は、水平幅の有効(4×4升枠を考慮)幅
「int minV;」は、垂直幅の有効(4×4升枠を考慮)幅
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Ave4M( ptrA + x + y * incA, incA, 4 );           // 4×4画素平均算出
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

「minH=pa->h-4;」は、水平有効幅算出
「minV=pa->v-4;」は、垂直有効幅算出
「ptrA=(double*)pa->adr;」は、処理ポインタのセット
「incA=pa->inc;」は、増加幅のセット
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は仮引数「TypeXY* xy,」
からXY座標を取り出す!
「if(x>=0&&x<minH&&y>=0&&y<minV){
buf=(int)Ave4M(ptrA+x+yincA,incA,4);}」は、if条件
「x>=0&&x<minH&&y>=0&&y<minV」で取り出したXY座
標が、有効な時「buf=(int)Ave4M(ptrA+x+yincA,incA,4);」と
サブルーチン関数「Ave4M(ptrA+x+y*incA,incA,4);」で
平均値算出し、「*buf=(int)・・・」は、整数型に型変換(
小数点以下切り捨て)し結果バッファに格納!
「else{*buf=0;}」は、XY座標が範囲外の場合で
「*buf=0.0;」とバッファに「0.0」を格納!

(4-14-138)関数「double CorrImage44XY(
TypeArray* pa,TypeArray* pb,
int x,int y){・・・}」

/************************************************************************************/
/*****      4×4画素正規化相関画像適応:個別                                  *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

double          CopyClear::CorrImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrB;                                               // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         incB;                                               // B配列:増加幅
    int         minH;                                               // ABの最小値:水平幅
    int         minV;                                               // ABの最小値:垂直幅

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h ) - 4;               // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v ) - 4;               // 垂直幅の最小値算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    ptrB = (BYTE*)pb->adr;                                          // B配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    incB = pb->inc;                                                 // B配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Corr44( ptrA + x + y * incA,                        // 4×4画素の正規相関を
                            ptrB + x + y * incB, incA, incB ) );    // 演算
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44XY()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の相関値算出関数です!

(B)関数「double CorrImage44XY()」の【返値】

関数返値として算出し相関値(一致率)を返す関数です!

(C)関数「CorrImage44XY()」の【仮引数】

double          CopyClear::CorrImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「int x」は、X座標
「int y」は、Y座標

(D)関数「CorrImage44XY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrB;                                               // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         incB;                                               // B配列:増加幅
    int         minH;                                               // ABの最小値:水平幅
    int         minV;                                               // ABの最小値:垂直幅

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h ) - 4;               // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v ) - 4;               // 垂直幅の最小値算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    ptrB = (BYTE*)pb->adr;                                          // B配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    incB = pb->inc;                                                 // B配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Corr44( ptrA + x + y * incA,                        // 4×4画素の正規相関を
                            ptrB + x + y * incB, incA, incB ) );    // 演算
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrB;                                               // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         incB;                                               // B配列:増加幅
    int         minH;                                               // ABの最小値:水平幅
    int         minV;                                               // ABの最小値:垂直幅

「BYTE* ptrA;」は、A画像用始点処理ポインタ
「BYTE* ptrB;」は、B画像用始点処理ポインタ
「int incA;」は、A画像増加幅
「int incB;」は、B画像増加幅
「int minH;」は、有効水平幅(4×4升枠考慮)
「int minV;」は、有効垂直幅(4×4升枠考慮)
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h ) - 4;               // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v ) - 4;               // 垂直幅の最小値算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    ptrB = (BYTE*)pb->adr;                                          // B配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    incB = pb->inc;                                                 // B配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Corr44( ptrA + x + y * incA,                        // 4×4画素の正規相関を
                            ptrB + x + y * incB, incA, incB ) );    // 演算
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h)-4;」は、水平画素数
の有効(最小で4×4升枠考慮)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v)-4;」は、垂直画素数の
有効(最小で4×4升枠考慮)サイズ算出!
「ptrA=(BYTE*)pa->adr;」は、A画像用始点処理ポインタ
をセット!
「ptrB=(BYTE*)pb->adr;」は、B画像用始点処理ポインタ
をセット!
「incA=pa->inc;」は、A画像増加幅をセット!
「incB=pb->inc;」は、B画像増加幅をセット!
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は仮引数「TypeXY* xy,」
からXY座標を取り出す!
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立・・}」は、
if条件「x>=0&&x<minH&&y>=0&&y<minV」でXY座標が
範囲内ならば、成立「return(Corr44(ptrA+x+yincA,
ptrB+x+yincB,incA,incB));」でサブルーチン関数
「Corr44()」で処理、★備考★実引数「ptrA+x+yincA,
ptrB+x+yincB,」でXY座標がポインタ演算でAB両画像
ともピンポイントで算出している事に注意!そしてif
不成立「else{return(0.0);}」は、「0.0」を関数辺値とし
返し関数終了!

(4-14-139)関数「void CorrImage44XY(
TypeArray* pa,
TypeArray* pb,TypeXY* xy,
double* buf,int size,int offX,
int offY){・・・}」

/************************************************************************************/
/*****      4×4画素正規化相関画像適応                                        *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

void            CopyClear::CorrImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrB;                                               // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         incB;                                               // B配列:増加幅
    int         minH;                                               // ABの最小値:水平幅
    int         minV;                                               // ABの最小値:垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h ) - 4;               // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v ) - 4;               // 垂直幅の最小値算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    ptrB = (BYTE*)pb->adr;                                          // B配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    incB = pb->inc;                                                 // B配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44( ptrA + x + y * incA,                     // 4×4画素の正規相関を
                                ptrB + x + y * incB, incA, incB );  // 演算
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44XY()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の相関値算出関数です!

(B)関数「void CorrImage44XY()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage44XY()」の【仮引数】

void            CopyClear::CorrImage44XY(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「TypeXY* xy,」は、XY座標バッファーで複数指定!
「double* buf,」は、結果格納バッファー!
「int size,」は、XY座標バッファー及び結果バッファー
のサイズです!
「int offX,」は、画像始点からのオフセット座標のX座標
「int offY 」は、画像始点からのオフセット座標のY座標

(D)関数「CorrImage44XY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrB;                                               // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         incB;                                               // B配列:増加幅
    int         minH;                                               // ABの最小値:水平幅
    int         minV;                                               // ABの最小値:垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h ) - 4;               // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v ) - 4;               // 垂直幅の最小値算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    ptrB = (BYTE*)pb->adr;                                          // B配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    incB = pb->inc;                                                 // B配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44( ptrA + x + y * incA,                     // 4×4画素の正規相関を
                                ptrB + x + y * incB, incA, incB );  // 演算
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrB;                                               // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         incB;                                               // B配列:増加幅
    int         minH;                                               // ABの最小値:水平幅
    int         minV;                                               // ABの最小値:垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

「BYTE* ptrA;」は、A画像用始点処理ポインタ
「BYTE* ptrB;」は、B画像用始点処理ポインタ
「int incA;」は、A画像増加幅
「int incB;」は、B画像増加幅
「int minH;」は、有効水平幅(4×4升枠考慮)
「int minV;」は、有効垂直幅(4×4升枠考慮)
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h ) - 4;               // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v ) - 4;               // 垂直幅の最小値算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    ptrB = (BYTE*)pb->adr;                                          // B配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    incB = pb->inc;                                                 // B配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44( ptrA + x + y * incA,                     // 4×4画素の正規相関を
                                ptrB + x + y * incB, incA, incB );  // 演算
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h)-4;」は、水平画素数
の有効(最小で4×4升枠考慮)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v)-4;」は、垂直画素数の
有効(最小で4×4升枠考慮)サイズ算出!
「ptrA=(BYTE*)pa->adr;」は、A画像用始点処理ポインタ
をセット!
「ptrB=(BYTE*)pb->adr;」は、B画像用始点処理ポインタ
をセット!
「incA=pa->inc;」は、A画像増加幅をセット!
「incB=pb->inc;」は、B画像増加幅をセット!
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は、XY座標バッファー
からローカル変数「int x;int y;」に取り出しオフセット
座標を加え、
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立・・}」は、
if条件「x>=0&&x<minH&&y>=0&&y<minV」でXY座標が
範囲内ならば、成立「return(Corr44(ptrA+x+yincA,
ptrB+x+yincB,incA,incB));」でサブルーチン関数
「Corr44()」で処理、★備考★実引数「ptrA+x+yincA,
ptrB+x+yincB,」でXY座標がポインタ演算でAB両画像
ともピンポイントで算出している事に注意!そしてif
不成立「else{return(0.0);}」は、「0.0」を関数辺値とし
返し関数終了!

(4-14-140)関数「double CorrImage44MyselfXY(
TypeArray* pa,int x,int y){・・・}」

/************************************************************************************/
/*****      4×4画素自己相関画像適応:個別                                    *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

double          CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Corr44Myself( ptrA + x + y * incA, incA ) );        // 4×4画素自己相関算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44MyselfXY()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を算出しますのでモット大きな値に成ります!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の相関値算出関数です!

(B)関数「double CorrImage44MyselfXY()」の【返値】

関数返値として算出し相関値(一致率)を返す関数です!
★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を算出しますのでモット大きな値に成ります!

(C)関数「CorrImage44MyselfXY()」の【仮引数】

double          CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){

「TypeArray* pa,」は、画像情報
「int x」は、X座標
「int y」は、Y座標

(D)関数「CorrImage44MyselfXY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Corr44Myself( ptrA + x + y * incA, incA ) );        // 4×4画素自己相関算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

「BYTE* ptrA;」は、A画像用始点処理ポインタ
「int incA;」は、A画像増加幅★備考★「int inc;」の
方が相応しいと思われるでしょう、この記載に成ったのは、
単にコピペで他の部分から流用したからです!同じ様に
処理ポインタも「BYTE* ptr;」の方が相応しいが、同じ
理由から、この変数名に成ったのです!
「int minH;」は、有効水平幅(4×4升枠考慮)
「int minV;」は、有効垂直幅(4×4升枠考慮)

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Corr44Myself( ptrA + x + y * incA, incA ) );        // 4×4画素自己相関算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0をセット
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h)-4;」は、水平画素数
の有効(最小で4×4升枠考慮)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v)-4;」は、垂直画素数の
有効(最小で4×4升枠考慮)サイズ算出!
「ptrA=(BYTE*)pa->adr;」は、A画像用始点処理ポインタ
をセット!
「incA=pa->inc;」は、A画像増加幅をセット!
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立・・}」は、
if条件「x>=0&&x<minH&&y>=0&&y<minV」でXY座標が
範囲内ならば、成立「return(Corr44Myself(
ptrA+x+yincA,incA));」でサブルーチン関数
「Corr44Myself()」で処理、★備考★実引数
「ptrA+x+yincA,」でXY座標がポインタ演算で画像ピン
ポイントで算出している事に注意!そしてif
不成立「else{return(0.0);}」は、「0.0」を関数辺値とし
返し関数終了!

(4-14-141)関数「void CorrImage44MyselfXY(
TypeArray* pa,TypeXY* xy,
double* buf,int size,int offX=0,
int offY=0){・・・}」

/************************************************************************************/
/*****      4×4画素自己相関画像適応                                          *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44Myself( ptrA + x + y * incA, incA );       // 4×4画素自己相関算出
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44MyselfXY()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を算出しますのでモット大きな値に成ります!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の相関値算出関数です!

(B)関数「void CorrImage44MyselfXY()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage44MyselfXY()」の【仮引数】

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){

「TypeArray* pa,」は、比較対象画像A
「TypeXY* xy,」は、XY座標バッファーで複数指定!
「double* buf,」は、結果格納バッファー!
「int size,」は、XY座標バッファー及び結果バッファー
のサイズです!
「int offX,」は、画像始点からのオフセット座標のX座標
「int offY 」は、画像始点からのオフセット座標のY座標

(D)関数「CorrImage44MyselfXY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44Myself( ptrA + x + y * incA, incA );       // 4×4画素自己相関算出
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

「BYTE* ptrA;」は、A画像用始点処理ポインタ
「int incA;」は、A画像増加幅★備考★「int inc;」の
方が相応しいと思われるでしょう、この記載に成ったのは、
単にコピペで他の部分から流用したからです!同じ様に
処理ポインタも「BYTE* ptr;」の方が相応しいが、同じ
理由から、この変数名に成ったのです!
「int minH;」は、有効水平幅(4×4升枠考慮)
「int minV;」は、有効垂直幅(4×4升枠考慮)
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44Myself( ptrA + x + y * incA, incA );       // 4×4画素自己相関算出
        }else{                                                      // 範囲外ならば
            *buf = 0.0;                                             // 0.0をセット
        }                                                           // 
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h)-4;」は、水平画素数
の有効(最小で4×4升枠考慮)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v)-4;」は、垂直画素数の
有効(最小で4×4升枠考慮)サイズ算出!
「ptrA=(BYTE*)pa->adr;」は、A画像用始点処理ポインタ
をセット!
「incA=pa->inc;」は、A画像増加幅をセット!
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は、XY座標バッファー
からローカル変数「int x;int y;」に取り出しオフセット
座標を加え、
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立・・}」は、
if条件「x>=0&&x<minH&&y>=0&&y<minV」でXY座標が
範囲内ならば、成立「buf=Corr44Myself(ptrA+x+yincA,
incA);」でサブルーチン関数「Corr44Myself()」で処理し
バッファー格納★備考★実引数
「ptrA+x+y*incA,」でXY座標がポインタ演算で画像ピン
ポイントで算出している事に注意!そしてif不成立
「else{*buf=0.0;}」は、「0.0」をバッファー格納!

(4-14-142)関数「void CorrImage44MyselfXY(
TypeArray* pa,TypeXY* xy,
double* buf,BYTE* bufAve,
int size,int offX=0,int offY=0){・・・}」

/************************************************************************************/
/*****      4×4画素自己相関画像適応+画像平均                                *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    BYTE*       bufAve,                                             // 結果バッファー:平均
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         ave;                                                // 平均値
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++, bufAve++ ){             // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf    = Corr44Myself( ptrA + x + y * incA, incA,      // 4×4画素自己相関算出
                                                            ave );  // (平均値も算出)
            *bufAve = ave;                                          // 平均値を格納
        }else{                                                      // 範囲外ならば
            *buf    = 0.0;                                          // 0.0をセット
            *bufAve = 0;                                            // 0をセット
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44MyselfXY()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を算出しますのでモット大きな値に成ります!
「Image」は、勿論、画像です!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の相関値算出関数です!

(B)関数「void CorrImage44MyselfXY()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage44MyselfXY()」の【仮引数】

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    double*     buf,                                                // 結果バッファー
    BYTE*       bufAve,                                             // 結果バッファー:平均
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){

「TypeArray* pa,」は、比較対象画像A
「TypeXY* xy,」は、XY座標バッファーで複数指定!
「double* buf,」は、結果(分散値)格納バッファー!
「BYTE* bufAve,」は、結果(平均値)格納バッファー!
「int size,」は、XY座標バッファー及び結果バッファー
のサイズです!
「int offX,」は、画像始点からのオフセット座標のX座標
「int offY 」は、画像始点からのオフセット座標のY座標
★備考★「BYTE* bufAve,」が有る事で多重定義(オーバー
ロード)関数の識別が出来ます!分散値だけで無く平均値
も必要な場合を考えた関数ですが、関数名を新規に考えるの
が面倒に成った(適切な名前より得られる引数追加の方が
簡単)のでコノ状態に成りました!平均値を使わない場合は
引数を記載しなければ良いとの考えです!多重定義の使い方
としてコレも有りなのだ!

(D)関数「CorrImage44MyselfXY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         ave;                                                // 平均値
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++, bufAve++ ){             // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf    = Corr44Myself( ptrA + x + y * incA, incA,      // 4×4画素自己相関算出
                                                            ave );  // (平均値も算出)
            *bufAve = ave;                                          // 平均値を格納
        }else{                                                      // 範囲外ならば
            *buf    = 0.0;                                          // 0.0をセット
            *bufAve = 0;                                            // 0をセット
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         ave;                                                // 平均値
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

「BYTE* ptrA;」は、A画像用始点処理ポインタ
「int incA;」は、A画像増加幅★備考★「int inc;」の
方が相応しいと思われるでしょう、この記載に成ったのは、
単にコピペで他の部分から流用したからです!同じ様に
処理ポインタも「BYTE* ptr;」の方が相応しいが、同じ
理由から、この変数名に成ったのです!
「int minH;」は、有効水平幅(4×4升枠考慮)
「int minV;」は、有効垂直幅(4×4升枠考慮)
「int ave;」は、個別の平均値
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++, bufAve++ ){             // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf    = Corr44Myself( ptrA + x + y * incA, incA,      // 4×4画素自己相関算出
                                                            ave );  // (平均値も算出)
            *bufAve = ave;                                          // 平均値を格納
        }else{                                                      // 範囲外ならば
            *buf    = 0.0;                                          // 0.0をセット
            *bufAve = 0;                                            // 0をセット
        }                                                           // 
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h)-4;」は、水平画素数
の有効(最小で4×4升枠考慮)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v)-4;」は、垂直画素数の
有効(最小で4×4升枠考慮)サイズ算出!
「ptrA=(BYTE*)pa->adr;」は、A画像用始点処理ポインタ
をセット!
「ptrB=(BYTE*)pb->adr;」は、B画像用始点処理ポインタ
をセット!
「incA=pa->inc;」は、A画像増加幅をセット!
「incB=pb->inc;」は、B画像増加幅をセット!
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は、XY座標バッファー
からローカル変数「int x;int y;」に取り出しオフセット
座標を加え、
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立・・}」は、
if条件「x>=0&&x<minH&&y>=0&&y<minV」でXY座標が
範囲内ならば、成立「return(Corr44Myself(
ptrA+x+yincA,incA));」でサブルーチン関数
「Corr44Myself()」で処理、★備考★実引数
「ptrA+x+yincA,」でXY座標がポインタ演算で画像ピン
ポイントで算出している事に注意!更に★注意★サブルー
チン関数「Corr44Myself(・・ave・・)」と多重定義(オー
バーロード)関数として「ave」を指定して平均値算出と
指定し無い関数が存在し、ココでは指定する関数を使用、
「*bufAve=ave;」は、平均値格納バッファー平均値を
格納!
そしてif不成立「else{*buf=0.0;*bufAve=0;}」は、
「0.0」を分散値、「0」を平均値とし引数辺値とし返し
関数終了!

(4-14-143)関数「void CorrImage44MyselfXY(
TypeArray* pa,TypeXY* xy,
int* buf,int size,int offX=0,
int offY=0){・・・}」

/************************************************************************************/
/*****      4×4画素自己相関画像適応                                          *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    int*        buf,                                                // 結果バッファー:整数値
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44Myself( ptrA + x + y * incA, incA );       // 4×4画素自己相関算出
        }else{                                                      // 範囲外ならば
            *buf = 0;                                               // 0をセット
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44MyselfXY()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を算出しますのでモット大きな値に成ります!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の相関値算出関数です!

(B)関数「void CorrImage44MyselfXY()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage44MyselfXY()」の【仮引数】

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    int*        buf,                                                // 結果バッファー:整数値
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){

「TypeArray* pa,」は、比較対象画像A
「TypeXY* xy,」は、XY座標バッファーで複数指定!
「int* buf,」は、結果格納バッファー!★備考★ここが、
多重定義(オーバーロード)で格納する型が違う事に留意
して下さい!
「int size,」は、XY座標バッファー及び結果バッファー
のサイズです!
「int offX,」は、画像始点からのオフセット座標のX座標
「int offY 」は、画像始点からのオフセット座標のY座標

(D)関数「CorrImage44MyselfXY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44Myself( ptrA + x + y * incA, incA );       // 4×4画素自己相関算出
        }else{                                                      // 範囲外ならば
            *buf = 0;                                               // 0をセット
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

「BYTE* ptrA;」は、A画像用始点処理ポインタ
「int incA;」は、A画像増加幅★備考★「int inc;」の
方が相応しいと思われるでしょう、この記載に成ったのは、
単にコピペで他の部分から流用したからです!同じ様に
処理ポインタも「BYTE* ptr;」の方が相応しいが、同じ
理由から、この変数名に成ったのです!
「int minH;」は、有効水平幅(4×4升枠考慮)
「int minV;」は、有効垂直幅(4×4升枠考慮)
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++ ){                       // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf = Corr44Myself( ptrA + x + y * incA, incA );       // 4×4画素自己相関算出
        }else{                                                      // 範囲外ならば
            *buf = 0;                                               // 0をセット
        }                                                           // 
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h)-4;」は、水平画素数
の有効(最小で4×4升枠考慮)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v)-4;」は、垂直画素数の
有効(最小で4×4升枠考慮)サイズ算出!
「ptrA=(BYTE*)pa->adr;」は、A画像用始点処理ポインタ
をセット!
「ptrB=(BYTE*)pb->adr;」は、B画像用始点処理ポインタ
をセット!
「incA=pa->inc;」は、A画像増加幅をセット!
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は、XY座標バッファー
からローカル変数「int x;int y;」に取り出しオフセット
座標を加え、
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立・・}」は、
if条件「x>=0&&x<minH&&y>=0&&y<minV」でXY座標が
範囲内ならば、成立「return(Corr44Myself(
ptrA+x+yincA,incA));」でサブルーチン関数
「Corr44Myself()」で処理、★備考★実引数
「ptrA+x+yincA,」でXY座標がポインタ演算で画像ピン
ポイントで算出している事に注意!
そしてif不成立「else{*buf=0;}」は、「0」を分散値
とし返し関数終了!

(4-14-144)関数「void CorrImage44MyselfXY(
TypeArray* pa,TypeXY* xy,
int* buf,BYTE* bufAve,int size,
int offX=0,int offY=0){・・・}」

/************************************************************************************/
/*****      4×4画素自己相関画像適応+画像平均                                *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    int*        buf,                                                // 結果バッファー:整数値
    BYTE*       bufAve,                                             // 結果バッファー:平均
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         ave;                                                // 平均値
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++, bufAve++ ){             // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf    = Corr44Myself( ptrA + x + y * incA, incA,      // 4×4画素自己相関算出
                                                            ave );  // (平均値も算出)
            *bufAve = ave;                                          // 平均値を格納
        }else{                                                      // 範囲外ならば
            *buf    = 0;                                            // 0をセット
            *bufAve = 0;                                            // 0をセット
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44MyselfXY()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を算出しますのでモット大きな値に成ります!
「Image」は、勿論、画像です!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の4×4升枠の相関値算出関数です!

(B)関数「void CorrImage44MyselfXY()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage44MyselfXY()」の【仮引数】

void            CopyClear::CorrImage44MyselfXY(
    TypeArray*  pa,                                                 // A配列
    TypeXY*     xy,                                                 // 探索座標列
    int*        buf,                                                // 結果バッファー:整数値
    BYTE*       bufAve,                                             // 結果バッファー:平均
    int         size,                                               // バッファーサイズ
    int         offX,                                               // X座標オフセット(省略時0)
    int         offY                                                // Y座標オフセット(省略時0)
){

「TypeArray* pa,」は、比較対象画像A
「TypeXY* xy,」は、XY座標バッファーで複数指定!
「int* buf,」は、結果格納バッファー!★備考★ここが、
多重定義(オーバーロード)で格納する型が違う事に留意
して下さい!
「BYTE* bufAve,」は、結果(平均値)格納バッファー!
「int size,」は、XY座標バッファー及び結果バッファー
のサイズです!
「int offX,」は、画像始点からのオフセット座標のX座標
「int offY 」は、画像始点からのオフセット座標のY座標
★備考★「BYTE* bufAve,」が有る事で多重定義(オーバー
ロード)関数の識別が出来ます!分散値だけで無く平均値
も必要な場合を考えた関数ですが、関数名を新規に考えるの
が面倒に成った(適切な名前より得られる引数追加の方が
簡単)のでコノ状態に成りました!平均値を使わない場合は
引数を記載しなければ良いとの考えです!多重定義の使い方
としてコレも有りなのだ!

(D)関数「CorrImage44MyselfXY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         ave;                                                // 平均値
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++, bufAve++ ){             // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf    = Corr44Myself( ptrA + x + y * incA, incA,      // 4×4画素自己相関算出
                                                            ave );  // (平均値も算出)
            *bufAve = ave;                                          // 平均値を格納
        }else{                                                      // 範囲外ならば
            *buf    = 0;                                            // 0をセット
            *bufAve = 0;                                            // 0をセット
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅
    int         ave;                                                // 平均値
    int         x;                                                  // X座標値
    int         y;                                                  // Y座標値
    int         i;                                                  // カウンタ

「BYTE* ptrA;」は、A画像用始点処理ポインタ
「int incA;」は、A画像増加幅★備考★「int inc;」の
方が相応しいと思われるでしょう、この記載に成ったのは、
単にコピペで他の部分から流用したからです!同じ様に
処理ポインタも「BYTE* ptr;」の方が相応しいが、同じ
理由から、この変数名に成ったのです!
「int minH;」は、有効水平幅(4×4升枠考慮)
「int minV;」は、有効垂直幅(4×4升枠考慮)
「int ave;」は、個別の平均値
「int x;」は、個別位置のX座標
「int y;」は、個別位置のY座標
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = pa->h - 4;                                               // 水平幅の有効範囲算出
    minV = pa->v - 4;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    for( i = 0; i < size; i++, xy++, buf++, bufAve++ ){             // 個数分
        x = xy->x + offX;                                           // 座標値を算出し
        y = xy->y + offY;                                           // 
        if( x >= 0 && x < minH && y >= 0 && y < minV ){             // 有効範囲内ならば
            *buf    = Corr44Myself( ptrA + x + y * incA, incA,      // 4×4画素自己相関算出
                                                            ave );  // (平均値も算出)
            *bufAve = ave;                                          // 平均値を格納
        }else{                                                      // 範囲外ならば
            *buf    = 0;                                            // 0をセット
            *bufAve = 0;                                            // 0をセット
        }                                                           // 
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h)-4;」は、水平画素数
の有効(最小で4×4升枠考慮)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v)-4;」は、垂直画素数の
有効(最小で4×4升枠考慮)サイズ算出!
「ptrA=(BYTE*)pa->adr;」は、A画像用始点処理ポインタ
をセット!
「incA=pa->inc;」は、A画像増加幅をセット!
「for(i=0;i<size;i++,xy++,buf++){・・ループ本体・・}」
は、ループ初期値「i=0;」ループ条件「i<size;」ループ
終了後処理「i++,xy++,buf++」と教科書的for構文での
アップカウンタ「i=0;」を条件「i<size;」増分「i++,」と
「0からsize未満」まで繰り返し同時に「xy++,buf++」と
バッファを示すポインタ増加でループ本体で
「x=xy->x+offX;y=xy->y+offY;」は、XY座標バッファー
からローカル変数「int x;int y;」に取り出しオフセット
座標を加え、
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立・・}」は、
if条件「x>=0&&x<minH&&y>=0&&y<minV」でXY座標が
範囲内ならば、成立「return(Corr44Myself(
buf=Corr44Myself(ptrA+x+yincA,incA,ave);」でサブルー
チン関数「Corr44Myself()」で処理、★備考★実引数
「ptrA+x+y*incA,」でXY座標がポインタ演算で画像ピン
ポイントで算出している事に注意!更に★注意★サブルー
チン関数「Corr44Myself(・・ave・・)」と多重定義(オー
バーロード)関数として「ave」を指定して平均値算出と
指定し無い関数が存在し、ココでは指定する関数を使用、
「*bufAve=ave;」は、平均値格納バッファー平均値を
格納!
そしてif不成立「else{*buf=0;*bufAve=0;}」は、
「0」を分散値、「0」を平均値とし引数辺値とし返し
関数終了!

(4-14-145)関数「void CorrImage44MyselfExtend(
TypeArray* pa,TypeXY* xy,
double* buf,int maxN,
int nStepH,int nStepV,
double tA,double tB){・・・}」

/************************************************************************************/
/*****      4×4画素自己相関画像適応:拡張                                    *****/
/*****      ☆4×4の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/*****      (1)概要でステップ毎に演算                                        *****/
/*****      (2)詳細で座標に従い細かく演算                                    *****/
/************************************************************************************/

int             CopyClear::CorrImage44MyselfExtend(
    TypeArray*  image,                                              // 画像
    TypeXY*     bufXY,                                              // 結果座標バッファー
    double*     buf,                                                // 結果バッファー
    int         maxN,                                               // 最大結果数
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    double      tA,                                                 // 最小概要しきい値
    double      tB                                                  // 最大概要しきい値
){
    int*        bufL;                                               // 結果バッファー:概要
    int         nH;                                                 // 水平方向個数
    int         nV;                                                 // 垂直方向個数
    int         nHV;                                                // 個数(nH*nV)
    int         n;                                                  // 計測個数

    GetHVCorrImage44Myself( image, nStepH, nStepV, nH, nV );        // 自己相関升目個数
    nHV  = nH * nV;                                                 // 個数(nH*nV)算出
    bufL = (int*)malloc( sizeof(int) * nHV );                       // 座標バッファーをメモリ確保
    if( bufL == 0 ){                                                // 確保失敗時
        return( STI_MEM );                                          // 左記を返す
    }                                                               // 
    CorrImage44Myself( image, bufL, nStepH, nStepV, nH, nV );       // 自己相関作成
    tA  = tA * tA * 16.0;                                           // 偏差値→判定値
    tB  = tB * tB * 16.0;                                           // 偏差値→判定値
    n   = makeCorrImageMyselfExtend( image, bufXY, bufL, maxN,      // 座標作成
                                nStepH, nStepV, tA, tB, 2, 2 );     // 
    CorrImage44MyselfXY( image, bufXY, buf, n, -2, -2 );            // 詳細自己相関作成
    free( bufL );                                                   // メモリ解放
    return( n );                                                    // 有効個数を返す
}

☆備考☆この関数はファイル「CopyClear430.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage44MyselfExtend()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を算出しますのでモット大きな値に成ります!
「Image」は、勿論、画像です!
「44」は、比較する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
「Extend」は、英単語「extend」、「拡張」を意味します!
詰り、前記した関数「CorrImage44Myself()」の機能を拡張
した関数です!

(B)関数「int CorrImage44MyselfExtend()」の【返値】

実行エラーコードとしては、「STI_MEM」を内部でメモリ
確保失敗した時に返します!正常動作した場合は、処理した
4×4升枠の数を返します!

(C)関数「CorrImage44MyselfExtend()」の【仮引数】

int             CopyClear::CorrImage44MyselfExtend(
    TypeArray*  image,                                              // 画像
    TypeXY*     bufXY,                                              // 結果座標バッファー
    double*     buf,                                                // 結果バッファー
    int         maxN,                                               // 最大結果数
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    double      tA,                                                 // 最小概要しきい値
    double      tB                                                  // 最大概要しきい値
){

「TypeArray* image,」は、対象画像情報
「TypeXY* bufXY,」は、XY座標バッファーで複数指定!
「double* buf,」は、結果格納バッファー!
「int maxN,」は、処理する4×4升枠の個数最大の数制限
「int nStepH,」は、4×4升枠の次への水平方向ステップ
「int nStepV,」は、4×4升枠の次への垂直方向ステップ
「double tA,」は、4×4升枠の相関値(分散値)下限で
「double tB」は、上限値で算出した相関値(分散値)が
下限から上限の間に有る様に調整する範囲です!

(D)関数「CorrImage44MyselfExtend()」の【アルゴリズム】

){
    int*        bufL;                                               // 結果バッファー:概要
    int         nH;                                                 // 水平方向個数
    int         nV;                                                 // 垂直方向個数
    int         nHV;                                                // 個数(nH*nV)
    int         n;                                                  // 計測個数

    GetHVCorrImage44Myself( image, nStepH, nStepV, nH, nV );        // 自己相関升目個数
    nHV  = nH * nV;                                                 // 個数(nH*nV)算出
    bufL = (int*)malloc( sizeof(int) * nHV );                       // 座標バッファーをメモリ確保
    if( bufL == 0 ){                                                // 確保失敗時
        return( STI_MEM );                                          // 左記を返す
    }                                                               // 
    CorrImage44Myself( image, bufL, nStepH, nStepV, nH, nV );       // 自己相関作成
    tA  = tA * tA * 16.0;                                           // 偏差値→判定値
    tB  = tB * tB * 16.0;                                           // 偏差値→判定値
    n   = makeCorrImageMyselfExtend( image, bufXY, bufL, maxN,      // 座標作成
                                nStepH, nStepV, tA, tB, 2, 2 );     // 
    CorrImage44MyselfXY( image, bufXY, buf, n, -2, -2 );            // 詳細自己相関作成
    free( bufL );                                                   // メモリ解放
    return( n );                                                    // 有効個数を返す
}

(D-1)ローカル変数

){
    int*        bufL;                                               // 結果バッファー:概要
    int         nH;                                                 // 水平方向個数
    int         nV;                                                 // 垂直方向個数
    int         nHV;                                                // 個数(nH*nV)
    int         n;                                                  // 計測個数

「int* bufL;」は、4×4升枠の相関値(分散値)内部算出
バッファー!
「int nH;」は、4×4升枠の水平方向個数
「int nV;」は、4×4升枠の垂直方向個数
「int nHV;」は、4×4升枠の垂直×方向個数
「int n;」は、結果として計測した4×4升枠の個数!

(D-2)アルゴリズムコード

    GetHVCorrImage44Myself( image, nStepH, nStepV, nH, nV );        // 自己相関升目個数
    nHV  = nH * nV;                                                 // 個数(nH*nV)算出
    bufL = (int*)malloc( sizeof(int) * nHV );                       // 座標バッファーをメモリ確保
    if( bufL == 0 ){                                                // 確保失敗時
        return( STI_MEM );                                          // 左記を返す
    }                                                               // 
    CorrImage44Myself( image, bufL, nStepH, nStepV, nH, nV );       // 自己相関作成
    tA  = tA * tA * 16.0;                                           // 偏差値→判定値
    tB  = tB * tB * 16.0;                                           // 偏差値→判定値
    n   = makeCorrImageMyselfExtend( image, bufXY, bufL, maxN,      // 座標作成
                                nStepH, nStepV, tA, tB, 2, 2 );     // 
    CorrImage44MyselfXY( image, bufXY, buf, n, -2, -2 );            // 詳細自己相関作成
    free( bufL );                                                   // メモリ解放
    return( n );                                                    // 有効個数を返す
}

「GetHVCorrImage44Myself(image,nStepH,nStepV,nH,nV);」
は、サブルーチン関数「GetHVCorrImage44Myself()」で
画像のサイズと水平垂直のステップ数で処理する水平垂直の
4×4升枠の個数算出!
「nHV=nHnV;」は、4×4升枠の垂直×方向個数算出!
「bufL=(int)malloc(sizeof(int)nHV);」は、4×4升枠
の自己相関値(分散値)内部算出用バッファーメモリ確保
「if(bufL==0){return(STI_MEM);}」は、バッファーメモリ
確保に失敗したらエラーコード「STI_MEM」を辺値とし返し
関数終了!
「CorrImage44Myself(image,bufL,nStepH,nStepV,nH,nV);」
は、サブルーチン関数「CorrImage44Myself()」で自己相関
算出!
「tA=tAtA16.0;tB=tBtB16.0;」は、4×4升枠なので
16画素、「tAtA」と自乗しているのは、分散値だから、
仮引数「double tA,double tB」と上下限の値を内部で使用
し易く変換した計算式です!
「n=makeCorrImageMyselfExtend(image,bufXY,bufL,maxN,
nStepH,nStepV,tA,tB,2,2);」は、サブルーチン関数「
makeCorrImageMyselfExtend()」で上下限の値等で自己相関
処理結果を加工し、仮引数「TypeXY* bufXY,」に座標の値を
セットし、有効な個数算出し「n」にセット!
「CorrImage44MyselfXY(image,bufXY,buf,n,-2,-2);」は、
サブルーチン関数「CorrImage44MyselfXY()」で座標指定の
自己相関処理を行い!
「free(bufL);」は、内部で確保したメモリを解放する関数
の後始末!
「return(n);」は、個数を関数辺値とし返し関数終了!

(4-14-146)関数「void CorrImage88(
TypeArray* pa,
TypeArray* pb,double* buf,
int nStepH,int nStepV,
int& resH,int& resV){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関画像適応                            *****/
/*****      ☆8×8の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::CorrImage88(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                              // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrAY;                                              // A配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅(nStepV単位)
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値
    int         i;                                                  // カウンタ

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 8 || minV < 8 ){                                     // サイズが8×8未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h     = ( minH - 8 ) / nStepH;                                  // 水平個数を算出
    v     = ( minV - 8 ) / nStepV;                                  // 垂直個数を算出
    resH  = h;                                                      // 返値:水平個数
    resV  = v;                                                      // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                         // A配列:処理ポインタ
    ptrBY = (BYTE*)pb->adr;                                         // B配列:処理ポインタ
    incA  = pa->inc * nStepV;                                       // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                                       // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){                // 垂直個数分
        ptrAX = ptrAY;                                              // A配列:水平始点
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH, ptrBX += nStepH ){   // 水平個数分
            *buf++ = Corr88( ptrAX, ptrBX, pa->inc, pb->inc );      // 8×8画素の正規相関を
        }                                                           // 算出しバッファーに格納
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「CorrImage88()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「88」は、比較する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します

(B)関数「void CorrImage88()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage88()」の【仮引数】

void            CopyClear::CorrImage88(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「double* buf,」は、結果相関値格納バッファー
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「CorrImage88()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                              // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrAY;                                              // A配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅(nStepV単位)
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値
    int         i;                                                  // カウンタ

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 8 || minV < 8 ){                                     // サイズが8×8未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h     = ( minH - 8 ) / nStepH;                                  // 水平個数を算出
    v     = ( minV - 8 ) / nStepV;                                  // 垂直個数を算出
    resH  = h;                                                      // 返値:水平個数
    resV  = v;                                                      // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                         // A配列:処理ポインタ
    ptrBY = (BYTE*)pb->adr;                                         // B配列:処理ポインタ
    incA  = pa->inc * nStepV;                                       // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                                       // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){                // 垂直個数分
        ptrAX = ptrAY;                                              // A配列:水平始点
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH, ptrBX += nStepH ){   // 水平個数分
            *buf++ = Corr88( ptrAX, ptrBX, pa->inc, pb->inc );      // 8×8画素の正規相関を
        }                                                           // 算出しバッファーに格納
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                              // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrAY;                                              // A配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incA;                                               // A配列:増加幅(nStepV単位)
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値
    int         i;                                                  // カウンタ

「BYTE* ptrAX;」は、A画像用X座標方向処理ポインタ
「BYTE* ptrBX;」は、B画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、A画像用Y座標方向処理ポインタ
「BYTE* ptrBY;」は、B画像用Y座標方向処理ポインタ
「int incA;」は、A画像増加幅
「int incB;」は、B画像増加幅
「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい
「int minH;」は、水平幅の最小値
「int minV;」は、垂直幅の最小値
★備考★上記「int minH;int minV;」は画像自体の
水平垂直幅で、「8×8升枠」を単位とした処理が可能な最小
(有効)画素サイズの算出です!
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 8 || minV < 8 ){                                     // サイズが8×8未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h     = ( minH - 8 ) / nStepH;                                  // 水平個数を算出
    v     = ( minV - 8 ) / nStepV;                                  // 垂直個数を算出
    resH  = h;                                                      // 返値:水平個数
    resV  = v;                                                      // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                         // A配列:処理ポインタ
    ptrBY = (BYTE*)pb->adr;                                         // B配列:処理ポインタ
    incA  = pa->inc * nStepV;                                       // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                                       // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){                // 垂直個数分
        ptrAX = ptrAY;                                              // A配列:水平始点
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH, ptrBX += nStepH ){   // 水平個数分
            *buf++ = Corr88( ptrAX, ptrBX, pa->inc, pb->inc );      // 8×8画素の正規相関を
        }                                                           // 算出しバッファーに格納
    }                                                               // 
}

「minH=((pa->h<pb->h)?pa->h:pb->h);」は、水平画素数の
有効(最小)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v);」は、垂直画素数の
有効(最小)サイズ算出!
「if(minH<8||minV<8){resH=0;resV=0;return;}」は、if
条件「minH<8||minV<8」有効サイズが「8×8」升枠が、
出来無いで「resH=0;resV=0;return;」と水平垂直の処理個
数が0に仮引数辺値にセットし、関数終了!
「h=(minH-8)/nStepH;v=(minV-8)/nStepV;resH=h;resV=v;」
は、「8×8」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;ptrBY=(BYTE*)pb->adr;」は、処理
し易い様にY座標方向始点をポインタ変数にセット!
「incA=pa->incnStepV;incB=pb->incnStepV;」は、画素
単位の「8×8」升枠でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA,ptrBY+=incB){・・外側ループ
本体・・}」は、ループ条件「--v>=0;」と良くこの解説で
説明して居る≪「--v」と値が変っても良い変数をダウンカ
ウンタに使用する事で教科書的な記述よりも現実のコンパイ
ラ環境で依り高速な機械コード(アセンブラ出力で確認)が
生成されるので私のソースコードでは多く採用≫とループ
本体終了後の処理「ptrAY+=incA,ptrBY+=incB」が、次の
X座標方向始点へ渡す為のY座標方向ポインタを垂直方向に
増加している!そして外側ループ本体
「ptrAX=ptrAY;ptrBX=ptrBY;」は、X座標方向始点を
ポインタ変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH,ptrBX+=nStepH){・・内側
ループ本体・・}」は、for構文の初期化「i=h;」で
ループカウンタ「i」をダウンカウンタとしセットし、ルー
プ条件「--i>=0;」と良くこの解説で説明して居る≪「--i」
と値が変っても良い変数をダウンカウンタに使用する事で
教科書的な記述よりも現実のコンパイラ環境で依り高速な
機械コード(アセンブラ出力で確認)が生成されるので私の
ソースコードでは多く採用≫とループ本体終了後の処理
「ptrAX+=nStepH,ptrBX+=nStepH」が、X座標方向ポインタ
を水平方向に増加している!そして内側ループ本体
「*buf++=Corr88(ptrAX,ptrBX,pa->inc,pb->inc);」は、
サブルーチン関数「Corr88()」で「8×8」升枠で相関値を
算出し「*buf++=・・」とバッファーに追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-147)関数「void GetHVCorrImage88(
TypeArray* pa,TypeArray* pb,
int nStepH,int nStepV,
int& resH,int& resV){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関画像適応用升目の個数取得            *****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::GetHVCorrImage88(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 8 || minV < 8 ){                                     // サイズが8×8未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( minH - 8 ) / nStepH;                                   // 水平個数を算出
    v    = ( minV - 8 ) / nStepV;                                   // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「GetHVCorrImage88()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対してを算出する関数「CorrImage88()」を意味≫し、
「Image」は、勿論、画像です!
「88」は、比較する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します!
この関数「GetHVCorrImage88()」は、その補助関数として
関数「CorrImage88()」の前に仮引数「int &resH,
int &resV」で水平垂直方向の結果個数を事前算出する事を
行います!

(B)関数「void GetHVCorrImage88()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVCorrImage88()」の【仮引数】

void            CopyClear::GetHVCorrImage88(
    TypeArray*  pa,                                                 // A配列
    TypeArray*  pb,                                                 // B配列
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「GetHVCorrImage88()」の【アルゴリズム】

){
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 8 || minV < 8 ){                                     // サイズが8×8未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( minH - 8 ) / nStepH;                                   // 水平個数を算出
    v    = ( minV - 8 ) / nStepV;                                   // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

(D-1)ローカル変数

){
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         minH;                                               // 水平幅の最小値
    int         minV;                                               // 垂直幅の最小値

「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい
「int minH;」は、水平幅の最小値
「int minV;」は、垂直幅の最小値
★備考★上記「int minH;int minV;」は画像自体の
水平垂直幅で、「8×8升枠」を単位とした処理が可能な最小
(有効)画素サイズの算出です!

(D-2)アルゴリズムコード

    minH = ( ( pa->h < pb->h ) ? pa->h : pb->h );                   // 水平幅の最小値算出
    minV = ( ( pa->v < pb->v ) ? pa->v : pb->v );                   // 垂直幅の最小値算出
    if( minH < 8 || minV < 8 ){                                     // サイズが8×8未満なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( minH - 8 ) / nStepH;                                   // 水平個数を算出
    v    = ( minV - 8 ) / nStepV;                                   // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

「minH=((pa->h<pb->h)?pa->h:pb->h);」は、水平画素数の
有効(最小)サイズ算出!
「minV=((pa->v<pb->v)?pa->v:pb->v);」は、垂直画素数の
有効(最小)サイズ算出!
「if(minH<8||minV<8){resH=0;resV=0;return;}」は、if
条件「minH<8||minV<8」有効サイズが「8×8」升枠が、
出来無いで「resH=0;resV=0;return;」と水平垂直の処理個
数が0に仮引数辺値にセットし、関数終了!
「h=(minH-8)/nStepH;v=(minV-8)/nStepV;resH=h;resV=v;」
は、「8×8」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
★備考★関数「CorrImage88()」で仮引数「double* buf,」
とバッファーを動的に必要なサイズ用意する必要が有るの
で、この関数で仮引数「int &resH,int &resV」で水平垂直
方向の結果個数を算出する事で用意しする事にしています!

(4-14-148)関数「void AverageImage88(
TypeArray* pa,BYTE* buf,
int nStepH,int nStepV,
int& resH,int& resV){・・・}」

/************************************************************************/
/*****      8×8画素画像平均適応                                  *****/
/*****      ☆8×8の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::AverageImage88(
    TypeArray*  pa,                                         // A配列
    BYTE*       buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = (int)Ave8M( ptrAX, pa->inc, 8 );       // 8×8画素平均算出
        }                                                   // 
    }                                                       // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage88()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「88」は、処理する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します

(B)関数「void AverageImage88()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「AverageImage88()」の【仮引数】

void            CopyClear::AverageImage88(
    TypeArray*  pa,                                         // A配列
    BYTE*       buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「BYTE* buf,」は、平均値格納バッファー
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「AverageImage88()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = (int)Ave8M( ptrAX, pa->inc, 8 );       // 8×8画素平均算出
        }                                                   // 
    }                                                       // 
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

「BYTE* ptrAX;」は、画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、画像用Y座標方向処理ポインタ
「int incA;」は、画像増加幅
「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = (int)Ave8M( ptrAX, pa->inc, 8 );       // 8×8画素平均算出
        }                                                   // 
    }                                                       // 
}

「if(pa->h<8||pa->v<8){resH=0;resV=0;return;}」は、
if条件「pa->h<8||pa->v<8」有効サイズが「8×8」升枠
が、出来無いで「resH=0;resV=0;return;」と
水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!
「h=(pa->h-8)/nStepH;v=(pa->v-8)/nStepV;」
は、「8×8」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;」は、処理し易い様にY座標方向
始点をポインタ変数にセット!
「incA=pa->inc*nStepV;」は、画素単位の「8×8」升枠
でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA){・・外側ループ本体・・}」は
ループ条件「--v>=0;」と良くこの解説で説明して居る≪
「--v」と値が変っても良い変数をダウンカウンタに使用
する事で教科書的な記述よりも現実のコンパイラ環境で依り
高速な機械コード(アセンブラ出力で確認)が生成されるの
で私のソースコードでは多く採用≫とループ本体終了後の
処理「ptrAY+=incA」が、次のX座標方向始点へ渡す為の
Y座標方向ポインタを垂直方向に増加している!そして外側
ループ本体「ptrAX=ptrAY;」は、X座標方向始点をポインタ
変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH){・・内側ループ本体・・
}」は、for構文の初期化「i=h;」でループカウンタ「i」
をダウンカウンタとしセットし、ループ条件「--i>=0;」と
良くこの解説で説明して居る≪「--i」と値が変っても良い
変数をダウンカウンタに使用する事で教科書的な記述よりも
現実のコンパイラ環境で依り高速な機械コード(アセンブラ
出力で確認)が生成されるので私のソースコードでは多く
採用≫とループ本体終了後の処理「ptrAX+=nStepH」が、
X座標方向ポインタを水平方向に増加している!そして内側
ループ本体
「*buf++=(int)Ave8M(ptrAX,pa->inc,8);」は、サブルーチ
ン関数「Ave8M(・・,8)」で「8×8」升枠で平均値を算出
し「*buf++=・・」とバッファーに「(int)」と整数型に
型変換≪小数点以下は切り捨て≫追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-149)関数「void AverageImage88(
TypeArray* pa,double* buf,
int nStepH,int nStepV,
int& resH,int& resV){・・・}」

/************************************************************************/
/*****      8×8画素画像平均適応                                  *****/
/*****      ☆8×8の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::AverageImage88(
    TypeArray*  pa,                                         // A配列
    double*     buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Ave8M( ptrAX, pa->inc, 8 );            // 8×8画素平均算出
        }                                                   // 
    }                                                       // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage88()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「88」は、処理する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します

(B)関数「void AverageImage88()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「AverageImage88()」の【仮引数】

void            CopyClear::AverageImage88(
    TypeArray*  pa,                                         // A配列
    double*     buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「double* buf,」は、平均値格納バッファー
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「AverageImage88()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Ave8M( ptrAX, pa->inc, 8 );            // 8×8画素平均算出
        }                                                   // 
    }                                                       // 
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

「BYTE* ptrAX;」は、画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、画像用Y座標方向処理ポインタ
「int incA;」は、画像増加幅
「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Ave8M( ptrAX, pa->inc, 8 );            // 8×8画素平均算出
        }                                                   // 
    }                                                       // 
}

「if(pa->h<8||pa->v<8){resH=0;resV=0;return;}」は、
if条件「pa->h<8||pa->v<8」有効サイズが「8×8」升枠
が、出来無いで「resH=0;resV=0;return;resH=h;resV=v;」と
水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!
「h=(pa->h-8)/nStepH;v=(pa->v-8)/nStepV;」
は、「8×8」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;」は、処理し易い様にY座標方向
始点をポインタ変数にセット!
「incA=pa->inc*nStepV;」は、画素単位の「8×8」升枠
でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA){・・外側ループ本体・・}」は
ループ条件「--v>=0;」と良くこの解説で説明して居る≪
「--v」と値が変っても良い変数をダウンカウンタに使用
する事で教科書的な記述よりも現実のコンパイラ環境で依り
高速な機械コード(アセンブラ出力で確認)が生成されるの
で私のソースコードでは多く採用≫とループ本体終了後の
処理「ptrAY+=incA」が、次のX座標方向始点へ渡す為の
Y座標方向ポインタを垂直方向に増加している!そして外側
ループ本体「ptrAX=ptrAY;」は、X座標方向始点をポインタ
変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH){・・内側ループ本体・・
}」は、for構文の初期化「i=h;」でループカウンタ「i」
をダウンカウンタとしセットし、ループ条件「--i>=0;」と
良くこの解説で説明して居る≪「--i」と値が変っても良い
変数をダウンカウンタに使用する事で教科書的な記述よりも
現実のコンパイラ環境で依り高速な機械コード(アセンブラ
出力で確認)が生成されるので私のソースコードでは多く
採用≫とループ本体終了後の処理「ptrAX+=nStepH」が、
X座標方向ポインタを水平方向に増加している!そして内側
ループ本体
「*buf++=Ave8M(ptrAX,pa->inc,8);」は、サブルーチン関数
「Ave8M(・・,8)」で「8×8」升枠で平均値を算出し
「*buf++=・・」とバッファーに追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-150)関数「void CorrImage88Myself(
TypeArray* pa,int* buf,
int nStepH,int nStepV,int &resH,int &resV){・・・}」

/************************************************************************/
/*****      8×8画素自己相関画像適応                              *****/
/*****      ☆8×8の基本単位毎に画像全体を演算しバッファーに格納☆*****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::CorrImage88Myself(
    TypeArray*  pa,                                         // A配列
    int*        buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Corr88Myself( ptrAX, pa->inc );        // 8×8画素自己相関算出
        }                                                   // 
    }                                                       // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「CorrImage88Myself()」の【関数名】

「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!★備考★相関値は、0.0から
1.0の間の値に成りますが、ココでは、計算途中の分散値
を整数型で算出しますのでモット大きな整数値に成ります!
「Image」は、勿論、画像です!
「88」は、比較する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!

(B)関数「void CorrImage88Myself()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「CorrImage88Myself()」の【仮引数】

void            CopyClear::CorrImage88Myself(
    TypeArray*  pa,                                         // A配列
    int*        buf,                                        // 結果バッファー
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「int* buf,」は、自己相関値格納バッファー
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int &resH,」は、水平方向の結果個数
「int &resV」は、垂直方向の結果個数

(D)関数「CorrImage88Myself()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Corr88Myself( ptrAX, pa->inc );        // 8×8画素自己相関算出
        }                                                   // 
    }                                                       // 
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         i;                                          // カウンタ

「BYTE* ptrAX;」は、画像用X座標方向処理ポインタ
「BYTE* ptrAY;」は、画像用Y座標方向処理ポインタ
「int incA;」は、画像増加幅
「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h     = ( pa->h - 8 ) / nStepH;                         // 水平個数を算出
    v     = ( pa->v - 8 ) / nStepV;                         // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr;                                 // A配列:処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA ){                       // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        for( i = h; --i >= 0; ptrAX += nStepH ){            // 水平個数分
            *buf++ = Corr88Myself( ptrAX, pa->inc );        // 8×8画素自己相関算出
        }                                                   // 
    }                                                       // 
}

「if(pa->h<8||pa->v<8){resH=0;resV=0;return;}」は、
if条件「pa->h<8||pa->v<8」有効サイズが「8×8」升枠
が、出来無いで「resH=0;resV=0;return;」と水平垂直の
処理個数が0に仮引数辺値にセットし、関数終了!
「h=(pa->h-8)/nStepH;v=(pa->v-8)/nStepV;」
は、「8×8」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!
「ptrAY=(BYTE*)pa->adr;」は、処理し易い様にY座標方向
始点をポインタ変数にセット!
「incA=pa->inc*nStepV;」は、画素単位の「8×8」升枠
でのポインタ増加幅を算出しセット!
次は、処理する二重ループで
「for(;--v>=0;ptrAY+=incA){・・外側ループ本体・・}」は
ループ条件「--v>=0;」と良くこの解説で説明して居る≪
「--v」と値が変っても良い変数をダウンカウンタに使用
する事で教科書的な記述よりも現実のコンパイラ環境で依り
高速な機械コード(アセンブラ出力で確認)が生成されるの
で私のソースコードでは多く採用≫とループ本体終了後の
処理「ptrAY+=incA」が、次のX座標方向始点へ渡す為の
Y座標方向ポインタを垂直方向に増加している!そして外側
ループ本体「ptrAX=ptrAY;」は、X座標方向始点をポインタ
変数にセット!
「for(i=h;--i>=0;ptrAX+=nStepH){・・内側ループ本体・・
}」は、for構文の初期化「i=h;」でループカウンタ「i」
をダウンカウンタとしセットし、ループ条件「--i>=0;」と
良くこの解説で説明して居る≪「--i」と値が変っても良い
変数をダウンカウンタに使用する事で教科書的な記述よりも
現実のコンパイラ環境で依り高速な機械コード(アセンブラ
出力で確認)が生成されるので私のソースコードでは多く
採用≫とループ本体終了後の処理「ptrAX+=nStepH」が、
X座標方向ポインタを水平方向に増加している!そして内側
ループ本体
「*buf++=Corr88Myself(ptrAX,pa->inc);」は、サブルー
チン関数「Corr88Myself()」で「8×8」升枠で分散値を
算出し「*buf++=・・」とバッファーに追加格納!
★備考★往々にして二次元の画像を二重ループで処理する
極標準的なループの組み合わせですので良く他の処理でも
基本的な処理として使用しています!

(4-14-151)関数「void GetHVCorrImage88Myself(
TypeArray* pa,int nStepH,
int nStepV,int &resH,int &resV){・・・}」

/************************************************************************/
/*****      8×8画素自己相関画像適応用升目の個数取得              *****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::GetHVCorrImage88Myself(
    TypeArray*  pa,                                         // A配列
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h    = ( pa->h - 8 ) / nStepH;                          // 水平個数を算出
    v    = ( pa->v - 8 ) / nStepV;                          // 垂直個数を算出
    resH = h;                                               // 返値:水平個数
    resV = v;                                               // 返値:垂直個数
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「GetHVCorrImage88Myself()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「88」は、比較する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します
「Myself」は、英単語「Myself」の意味通り「自分自身」
です⇒仮引数「TypeArray* pa,」と画像情報が一つしか
無い事に注目して下さい!、詰り、自己相関を算出します!
ここは、自己相関の補助関数として「int* buf,」を
多重定義(オーバーロード)関数から外す事で自己相関を
算出で無く、仮引数「int &resH,int &resV」の値を算出
する事で事前にバッファー取得の予備に使用します!

(B)関数「void GetHVCorrImage88Myself()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVCorrImage88Myself()」の【仮引数】

void            CopyClear::GetHVCorrImage88Myself(
    TypeArray*  pa,                                         // A配列
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、処理対象画像
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「GetHVCorrImage88Myself()」の【アルゴリズム】

){
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h    = ( pa->h - 8 ) / nStepH;                          // 水平個数を算出
    v    = ( pa->v - 8 ) / nStepV;                          // 垂直個数を算出
    resH = h;                                               // 返値:水平個数
    resV = v;                                               // 返値:垂直個数
}

(D-1)ローカル変数

){
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)

「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい

(D-2)アルゴリズムコード

    if( pa->h < 8 || pa->v < 8 ){                           // サイズが8×8未満なら
        resH = 0;                                           // 個数の返事を0にして
        resV = 0;                                           // 
        return;                                             // 終了
    }                                                       // 
    h    = ( pa->h - 8 ) / nStepH;                          // 水平個数を算出
    v    = ( pa->v - 8 ) / nStepV;                          // 垂直個数を算出
    resH = h;                                               // 返値:水平個数
    resV = v;                                               // 返値:垂直個数
}

「if(pa->h<8||pa->v<8){resH=0;resV=0;return;}」は、
if条件「pa->h<8||pa->v<8」有効サイズが「8×8」升枠
が、出来無いで「resH=0;resV=0;return;resH=h;resV=v;」と
水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!
「h=(pa->h-8)/nStepH;v=(pa->v-8)/nStepV;」
は、「8×8」升枠が水平垂直に何個有るか「h・v」に算出
し仮引数「int &resH,int &resV」に辺値としセット!

(4-14-152)関数「void SearchCorrImage88(
TypeArray* pa,
TypeArray* pb,double* buf,
int nStepH,int nStepV,
int &resH,int &resV){・・・}

/****************************************************************************/
/*****      8×8画素正規化相関サーチ画像適応                          *****/
/*****      ☆8×8の基本単位毎に画像をサーチし結果をバッファーに格納☆*****/
/*****      引数返値:水平個数                                          *****/
/*****      引数返値:垂直個数                                          *****/
/****************************************************************************/

void            CopyClear::SearchCorrImage88(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         sumA;                                               // 合計A(及び自己相関)
    int         avA;                                                // 平均A
    int         avB;                                                // 平均B
    int         i;                                                  // カウンタ
    int         j;                                                  // カウンタ

    if( pa->h < 8 || pa->v < 8 || pb->h < 8 || pb->v < 8 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h      = ( pb->h - 8 ) / nStepH;                                // 水平個数を算出
    v      = ( pb->v - 8 ) / nStepV;                                // 垂直個数を算出
    resH   = h;                                                     // 返値:水平個数
    resV   = v;                                                     // 返値:垂直個数
    ptrA   = (BYTE*)pa->adr;                                        // A配列:処理ポインタ
    ptrBY  = (BYTE*)pb->adr;                                        // B配列:処理ポインタ
    incB   = pb->inc * nStepV;                                      // B配列:増加幅(nStepV単位)
    *buf++ = Corr88First( ptrA, ptrBY, pa->inc, pb->inc,            // 先頭の時の相関値算出
                                                avA, avB, sumA );   // 
    for( i = 0; i < v; i++, ptrBY += incB ){                        // 垂直個数分
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( j = 0; j < h; j++, ptrBX += nStepH ){                  // 水平個数分
            if( !( i == 0 && j == 0 ) ){                            // 先頭以外ならば
                *buf++ = Corr88Second( ptrA, ptrBX,                 // 8×8画素の正規相関を
                                pa->inc, pb->inc, avA, avB, sumA ); // 算出しバッファーに格納
            }                                                       // 
        }                                                           // 
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「SearchCorrImage88()」の【関数名】

「Search」は、英単語「Search」で「探す・探索」です!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「88」は、比較する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します!

(B)関数「void SearchCorrImage88()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「SearchCorrImage88()」の【仮引数】

void            CopyClear::SearchCorrImage88(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    double*     buf,                                                // 結果バッファー
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A≪テンプレート画像≫
「TypeArray* pb,」は、比較対象画像B≪サーチ対象画像≫
「double* buf,」は、結果相関値格納バッファー
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「SearchCorrImage88()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         sumA;                                               // 合計A(及び自己相関)
    int         avA;                                                // 平均A
    int         avB;                                                // 平均B
    int         i;                                                  // カウンタ
    int         j;                                                  // カウンタ

    if( pa->h < 8 || pa->v < 8 || pb->h < 8 || pb->v < 8 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h      = ( pb->h - 8 ) / nStepH;                                // 水平個数を算出
    v      = ( pb->v - 8 ) / nStepV;                                // 垂直個数を算出
    resH   = h;                                                     // 返値:水平個数
    resV   = v;                                                     // 返値:垂直個数
    ptrA   = (BYTE*)pa->adr;                                        // A配列:処理ポインタ
    ptrBY  = (BYTE*)pb->adr;                                        // B配列:処理ポインタ
    incB   = pb->inc * nStepV;                                      // B配列:増加幅(nStepV単位)
    *buf++ = Corr88First( ptrA, ptrBY, pa->inc, pb->inc,            // 先頭の時の相関値算出
                                                avA, avB, sumA );   // 
    for( i = 0; i < v; i++, ptrBY += incB ){                        // 垂直個数分
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( j = 0; j < h; j++, ptrBX += nStepH ){                  // 水平個数分
            if( !( i == 0 && j == 0 ) ){                            // 先頭以外ならば
                *buf++ = Corr88Second( ptrA, ptrBX,                 // 8×8画素の正規相関を
                                pa->inc, pb->inc, avA, avB, sumA ); // 算出しバッファーに格納
            }                                                       // 
        }                                                           // 
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    BYTE*       ptrBX;                                              // B配列:処理ポインタ
    BYTE*       ptrBY;                                              // B配列:処理ポインタ
    int         incB;                                               // B配列:増加幅(nStepV単位)
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)
    int         sumA;                                               // 合計A(及び自己相関)
    int         avA;                                                // 平均A
    int         avB;                                                // 平均B
    int         i;                                                  // カウンタ
    int         j;                                                  // カウンタ

「BYTE* ptrAX;」は、A画像用X座標方向処理ポインタ
「BYTE* ptrBX;」は、B画像用X座標方向処理ポインタ
「BYTE* ptrBY;」は、B画像用Y座標方向処理ポインタ
「int incB;」は、B画像増加幅
「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい
「int sumA;」は、A画像用合計値、及び分散値算出用
「int avA;」は、A画像平均値
「int avB;」は、B画像平均値
「int i;」は、ループカウンタ外側
「int j;」は、ループカウンタ内側

(D-2)アルゴリズムコード

    if( pa->h < 8 || pa->v < 8 || pb->h < 8 || pb->v < 8 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h      = ( pb->h - 8 ) / nStepH;                                // 水平個数を算出
    v      = ( pb->v - 8 ) / nStepV;                                // 垂直個数を算出
    resH   = h;                                                     // 返値:水平個数
    resV   = v;                                                     // 返値:垂直個数
    ptrA   = (BYTE*)pa->adr;                                        // A配列:処理ポインタ
    ptrBY  = (BYTE*)pb->adr;                                        // B配列:処理ポインタ
    incB   = pb->inc * nStepV;                                      // B配列:増加幅(nStepV単位)
    *buf++ = Corr88First( ptrA, ptrBY, pa->inc, pb->inc,            // 先頭の時の相関値算出
                                                avA, avB, sumA );   // 
    for( i = 0; i < v; i++, ptrBY += incB ){                        // 垂直個数分
        ptrBX = ptrBY;                                              // B配列:水平始点
        for( j = 0; j < h; j++, ptrBX += nStepH ){                  // 水平個数分
            if( !( i == 0 && j == 0 ) ){                            // 先頭以外ならば
                *buf++ = Corr88Second( ptrA, ptrBX,                 // 8×8画素の正規相関を
                                pa->inc, pb->inc, avA, avB, sumA ); // 算出しバッファーに格納
            }                                                       // 
        }                                                           // 
    }                                                               // 
}

「if(pa->h<8||pa->v<8||pb->h<8||pb->v<8){
resH=0;resV=0;return;}」は、if条件
「pa->h<8||pa->v<8||pb->h<8||pb->v<8」有効サイズが
「8×8」升枠が、出来無いで「resH=0;resV=0;return;」
と水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!は、
「h=(pb->h-8)/nStepH;v=(pb->v-8)/nStepV;」は、水平垂直
の処理升の個数を算出!
「resH=h;resV=v;」は、仮引数「int &resH,int &resV」に
引数辺値とし格納!
「ptrA=(BYTE*)pa->adr;ptrBY=(BYTE*)pb->adr;」は、処理
し易い様にA画像用X座標方向とY座標方向始点をポインタ
変数にセット!
「incB=pb->inc*nStepV;」は、画素単位の「8×8」升枠で
のポインタ増加幅を算出しセット!
「*buf++=Corr88First(ptrA,ptrBY,pa->inc,pb->inc,avA,
avB,sumA);」は、サブルーチン関数「Corr88First()」で
最初の「8×8」升枠の処理を行います!
次は、処理する二重ループで
「for(i=0;i<v;i++,ptrBY+=incB){・・外側ループ本体・・}
」は、ループ初期値「i=0;」ループ条件「i<v;」ループ終了
後処理「i++,ptrBY+=incB」と教科書的for構文でのアッ
プカウンタ「i=0;」を条件「i<v;」増分「i++,」と「0から
v未満」まで繰り返し同時に「ptrBY+=incB」と垂直方向に
ポインタ増加で外側ループ本体で
「ptrBX=ptrBY;」は、B画像用X座標方向処理ポインタを
セットし、内側ループ「for(j=0;j<h;j++,ptrBX+=nStepH){
・・内側ループ本体・・}」とし繰り返します!そのfor
構文「for(j=0;j<h;j++,ptrBX+=nStepH)」は、ループ初期
値「j=0;」ループ条件「j<h;」ループ終了後処理
「j++,ptrBX+=nStepH」と教科書的for構文でのアップカ
ウンタ「j=0;」を条件「j<h;」増分「j++,」と「0から
h未満」まで繰り返し同時に「ptrBX+=nStepH」と水平方向にポインタ増加でif構文「if(!(i==0&&j==0)){
*buf++=Corr88Second(ptrA,ptrBX,pa->inc,pb->inc,avA,
avB,sumA);}」とif条件「!(i==0&&j==0)」詰り、ループカ
ウンタ「i,j」が同時に「0」最初以外で成立中身「*buf++=
Corr88Second(ptrA,ptrBX,pa->inc,pb->inc,avA,avB,sumA);
」とサブルーチン関数「Corr88Second()」で処理します!
★備考★最初の処理が、サブルーチン関数「Corr88First()
」で専用の処理を行うので関数名「Corr88First」に
「First」を明示し、それ以外を通常処理として行うので
関数名「Corr88Second」と「Second」を明示しました!
コノ「First」・「Second」は、他の関数でも同じ様な関係
で使用しますので注意して下さい!

(4-14-153)関数「void GetHVSearchCorrImage88(
TypeArray* pa,TypeArray* pb,
int nStepH,int nStepV,
int &resH,int &resV){・・・}

/************************************************************************/
/*****      8×8画素正規化相関サーチ画像適応用升目の個数取得      *****/
/*****      引数返値:水平個数                                      *****/
/*****      引数返値:垂直個数                                      *****/
/************************************************************************/

void            CopyClear::GetHVSearchCorrImage88(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)

    if( pa->h < 8 || pa->v < 8 || pb->h < 8 || pb->v < 8 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( pb->h - 8 ) / nStepH;                                  // 水平個数を算出
    v    = ( pb->v - 8 ) / nStepV;                                  // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「GetHVSearchCorrImage88()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Search」は、英単語「Search」で「探す・探索」です!
「Corr」は、英単語「correlation」の省略で「相関」を
意味します!相関とは、「二つの物が、関わり合いを持つ」
と有る様に二つの画像を比較して相関値≪ここでは、1に
近い程高い相関値が有ると0.0から1.0の相関値を画像
に対して≫を算出します!
「Image」は、勿論、画像です!
「88」は、比較する画像の範囲として「縦×横=8×8=
64画素」のサイズを意味します
ここは、画像サーチの補助関数として「double* buf,」を
算出で無く、仮引数「int &resH,int &resV」の値を算出
する事で事前にバッファー取得の予備に使用します!

(B)関数「void GetHVSearchCorrImage88()」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVSearchCorrImage88()」の【仮引数】

void            CopyClear::GetHVSearchCorrImage88(
    TypeArray*  pa,                                                 // A配列:サーチ対象
    TypeArray*  pb,                                                 // B配列:サーチ範囲
    int         nStepH,                                             // 水平方向次点ステップ数
    int         nStepV,                                             // 垂直方向次点ステップ数
    int&        resH,                                               // 返値:取得する水平個数
    int&        resV                                                // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A≪テンプレート画像≫
「TypeArray* pb,」は、比較対象画像B≪サーチ対象画像≫
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「GetHVSearchCorrImage88()」の【アルゴリズム】

){
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)

    if( pa->h < 8 || pa->v < 8 || pb->h < 8 || pb->v < 8 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( pb->h - 8 ) / nStepH;                                  // 水平個数を算出
    v    = ( pb->v - 8 ) / nStepV;                                  // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

(D-1)ローカル変数

){
    int         h;                                                  // 水平幅(8×8の個数)
    int         v;                                                  // 垂直幅(8×8の個数)

「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
★備考★上記「int h;int v;」は画像自体の水平垂直幅で
無く、「8×8升枠」を単位とした処理個数に注意して下さい

(D-2)アルゴリズムコード

    if( pa->h < 8 || pa->v < 8 || pb->h < 8 || pb->v < 8 ){         // サーチに不適合なら
        resH = 0;                                                   // 個数の返事を0にして
        resV = 0;                                                   // 
        return;                                                     // 終了
    }                                                               // 
    h    = ( pb->h - 8 ) / nStepH;                                  // 水平個数を算出
    v    = ( pb->v - 8 ) / nStepV;                                  // 垂直個数を算出
    resH = h;                                                       // 返値:水平個数
    resV = v;                                                       // 返値:垂直個数
}

「if(pa->h<8||pa->v<8||pb->h<8||pb->v<8){
resH=0;resV=0;return;}」は、if条件
「pa->h<8||pa->v<8||pb->h<8||pb->v<8」有効サイズが
「8×8」升枠が、出来無いで「resH=0;resV=0;return;」
と水平垂直の処理個数が0に仮引数辺値にセットし、
関数終了!は、
「h=(pb->h-8)/nStepH;v=(pb->v-8)/nStepV;」は、水平垂直
の処理升の個数を算出!
「resH=h;resV=v;」は、仮引数「int &resH,int &resV」に
引数辺値とし格納!

(4-14-154)関数「void ReductImage88Ave(TypeArray* ps,TypeArray* pd){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関用画像圧縮(平均値)                *****/
/*****      ☆任意の16×16画素で構成される画像を                *****/
/*****      ☆8×8の基本単位毎に圧縮:平均☆                      *****/
/************************************************************************/

void            CopyClear::ReductImage88Ave(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Ave( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (平均値圧縮)
    }                                                           // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void ReductImage88Ave()」の【関数名】

「Reduct」は、英単語「reduction」で縮小、
「Image」は、勿論、画像「88」は、16×16升枠で縮小したら8×8升枠に成ります!
「Ave」は、英単語「Average」省略形で「平均値」を意味し、ここでは、縮小する時、平均値で縮小する事を示します!

(B)関数「void ReductImage88Ave()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「ReductImage88Ave()」の【仮引数】

void            CopyClear::ReductImage88Ave(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){

「TypeArray* ps,」は、S(元)画像情報
「TypeArray* pd」は、D(結果)画像情報

(D)関数「ReductImage88Ave()」の【アルゴリズム】

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Ave( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (平均値圧縮)
    }                                                           // 
}

(D-1)ローカル変数

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

「BYTE* ptrSX;」は、S画像X座標方向処理ポインタ
「BYTE* ptrDX;」は、D画像X座標方向処理ポインタ
「BYTE* ptrSY;」は、S画像Y座標方向処理ポインタ
「BYTE* ptrDY;」は、D画像Y座標方向処理ポインタ
「int incS;」は、S画像増加幅
「int incD;」は、D画像増加幅
「int h;」は、水平幅(16×16の個数)
「int v;」は、垂直幅(16×16の個数)
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Ave( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (平均値圧縮)
    }                                                           // 
}

「h=ps->h/2;h=((h<pd->h)?h:pd->h)/8;」は、SD画像
サイズから水平幅(16×16の個数)算出!
「v=ps->v/2;v=((v<pd->v)?v:pd->v)/8;」は、SD画像
サイズから垂直幅(16×16の個数)算出!
「ptrSY=(BYTE*)ps->adr;ptrDY=(BYTE*)pd->adr;」は、
SD画像の処理ポインタをセット!
「incS=ps->inc16;」は、S画像を16×16升枠単位垂直
増加幅算出!
「incD=pd->inc8;」は、D画像を8×8升枠単位垂直
増加幅算出!
「for(;--v>=0;ptrSY+=incS,ptrDY+=incD){・・外側ループ
本体・・}」は、forループ構文で良くこの解説で紹介
するループ条件「--v>=0;」で垂直個数繰り返し、中身で
垂直方向の処理を行い、ループ後置「ptrSY+=incS,
ptrDY+=incD」でSD両者の垂直方向処理ポインタを進行!
外側ループ本体「ptrSX=ptrSY;ptrDX=ptrDY;」は、SD両者
の水平方向処理ポインタの始点をセット、
「for(i=h;--i>=0;ptrSX+=16,ptrDX+=8){Reduct88Ave(
ptrSX,ptrDX,ps->inc,pd->inc);}」は、forループ構文で
内側のループ初期化「i=h;」で一旦ループカウンタをセット
ループ条件「--i>=0;」水平方向繰り返し、中身でサブルー
チン関数「Reduct88Ave()」でS画像を16×16升枠単位から
D画像を8×8升枠単位に平均値で縮小します!

本日(2月4)の講義はココまでとします!これで
正規相関系「public:属性」の関数の解説を始めました!
尚、この続きは、引き続き、この解説文章に追記して行きま
す!引き続き御贔屓をお願いします!

(4-14-155)関数「void ReductImage88Min(
TypeArray* ps,TypeArray* pd){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関用画像圧縮(最小値)                *****/
/*****      ☆任意の16×16画素で構成される画像を                *****/
/*****      ☆8×8の基本単位毎に圧縮:最小☆                      *****/
/************************************************************************/

void            CopyClear::ReductImage88Min(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Min( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (最小値圧縮)
    }                                                           // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void ReductImage88Min()」の【関数名】

「Reduct」は、英単語「reduction」で縮小、
「Image」は、勿論、画像「88」は、16×16升枠で縮小したら8×8升枠に成ります!「Min」は、英単語「minimum」の省略形で色抽出方法が、「最小値」を意味し、ここでは、
縮小する時、最小値で縮小する事を示します!

(B)関数「void ReductImage88Min()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「ReductImage88Min()」の【仮引数】

void            CopyClear::ReductImage88Min(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){

「TypeArray* ps,」は、S(元)画像情報
「TypeArray* pd」は、D(結果)画像情報

(D)関数「ReductImage88Min()」の【アルゴリズム】

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Min( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (最小値圧縮)
    }                                                           // 
}

(D-2)ローカル変数

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

「BYTE* ptrSX;」は、S画像X座標方向処理ポインタ
「BYTE* ptrDX;」は、D画像X座標方向処理ポインタ
「BYTE* ptrSY;」は、S画像Y座標方向処理ポインタ
「BYTE* ptrDY;」は、D画像Y座標方向処理ポインタ
「int incS;」は、S画像増加幅
「int incD;」は、D画像増加幅
「int h;」は、水平幅(16×16の個数)
「int v;」は、垂直幅(16×16の個数)
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Min( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (最小値圧縮)
    }                                                           // 
}

「h=ps->h/2;h=((h<pd->h)?h:pd->h)/8;」は、SD画像
サイズから水平幅(16×16の個数)算出!
「v=ps->v/2;v=((v<pd->v)?v:pd->v)/8;」は、SD画像
サイズから垂直幅(16×16の個数)算出!
「ptrSY=(BYTE*)ps->adr;ptrDY=(BYTE*)pd->adr;」は、
SD画像の処理ポインタをセット!
「incS=ps->inc16;」は、S画像を16×16升枠単位垂直
増加幅算出!
「incD=pd->inc8;」は、D画像を8×8升枠単位垂直
増加幅算出!
「for(;--v>=0;ptrSY+=incS,ptrDY+=incD){・・外側ループ
本体・・}」は、forループ構文で良くこの解説で紹介
するループ条件「--v>=0;」で垂直個数繰り返し、中身で
垂直方向の処理を行い、ループ後置「ptrSY+=incS,
ptrDY+=incD」でSD両者の垂直方向処理ポインタを進行!
外側ループ本体「ptrSX=ptrSY;ptrDX=ptrDY;」は、SD両者
の水平方向処理ポインタの始点をセット、
「for(i=h;--i>=0;ptrSX+=16,ptrDX+=8){Reduct88Min(
ptrSX,ptrDX,ps->inc,pd->inc);}」は、forループ構文で
内側のループ初期化「i=h;」で一旦ループカウンタをセット
ループ条件「--i>=0;」水平方向繰り返し、中身でサブルー
チン関数「Reduct88Min()」でS画像を16×16升枠単位から
D画像を8×8升枠単位に最小値で縮小します!

(4-14-156)関数「void ReductImage88Max(
TypeArray* ps,TypeArray* pd){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関用画像圧縮(最大値)                *****/
/*****      ☆任意の16×16画素で構成される画像を                *****/
/*****      ☆8×8の基本単位毎に圧縮:最大☆                      *****/
/************************************************************************/

void            CopyClear::ReductImage88Max(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Max( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (最大値圧縮)
    }                                                           // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void ReductImage88Max()」の【関数名】


「Reduct」は、英単語「reduction」で縮小、
「Image」は、勿論、画像「88」は、16×16升枠で縮小したら8×8升枠に成ります!「Max」は、英単語「Maximum」の省略形で色抽出方法が、「最大値」を意味し、ここでは、
縮小する時、最大値で縮小する事を示します!

(B)関数「void ReductImage88Max()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「ReductImage88Max()」の【仮引数】

void            CopyClear::ReductImage88Max(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){

「TypeArray* ps,」は、S(元)画像情報
「TypeArray* pd」は、D(結果)画像情報

(D)関数「ReductImage88Max()」の【アルゴリズム】

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Max( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (最大値圧縮)
    }                                                           // 
}

(D-1)ローカル変数

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

「BYTE* ptrSX;」は、S画像X座標方向処理ポインタ
「BYTE* ptrDX;」は、D画像X座標方向処理ポインタ
「BYTE* ptrSY;」は、S画像Y座標方向処理ポインタ
「BYTE* ptrDY;」は、D画像Y座標方向処理ポインタ
「int incS;」は、S画像増加幅
「int incD;」は、D画像増加幅
「int h;」は、水平幅(16×16の個数)
「int v;」は、垂直幅(16×16の個数)
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Max( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (最大値圧縮)
    }                                                           // 
}

「h=ps->h/2;h=((h<pd->h)?h:pd->h)/8;」は、SD画像
サイズから水平幅(16×16の個数)算出!
「v=ps->v/2;v=((v<pd->v)?v:pd->v)/8;」は、SD画像
サイズから垂直幅(16×16の個数)算出!
「ptrSY=(BYTE*)ps->adr;ptrDY=(BYTE*)pd->adr;」は、
SD画像の処理ポインタをセット!
「incS=ps->inc16;」は、S画像を16×16升枠単位垂直
増加幅算出!
「incD=pd->inc8;」は、D画像を8×8升枠単位垂直
増加幅算出!
「for(;--v>=0;ptrSY+=incS,ptrDY+=incD){・・外側ループ
本体・・}」は、forループ構文で良くこの解説で紹介
するループ条件「--v>=0;」で垂直個数繰り返し、中身で
垂直方向の処理を行い、ループ後置「ptrSY+=incS,
ptrDY+=incD」でSD両者の垂直方向処理ポインタを進行!
外側ループ本体「ptrSX=ptrSY;ptrDX=ptrDY;」は、SD両者
の水平方向処理ポインタの始点をセット、
「for(i=h;--i>=0;ptrSX+=16,ptrDX+=8){Reduct88Max(
ptrSX,ptrDX,ps->inc,pd->inc);}」は、forループ構文で
内側のループ初期化「i=h;」で一旦ループカウンタをセット
ループ条件「--i>=0;」水平方向繰り返し、中身でサブルー
チン関数「Reduct88Max()」でS画像を16×16升枠単位から
D画像を8×8升枠単位に最大値で縮小します!

(4-14-157)関数「void ReductImage88Two(
TypeArray* ps,TypeArray* pd){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関用画像圧縮(昇順に2番目の値)      *****/
/*****      ☆任意の16×16画素で構成される画像を                *****/
/*****      ☆8×8の基本単位毎に圧縮:2番目☆                    *****/
/************************************************************************/

void            CopyClear::ReductImage88Two(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Two( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (2番目の値で圧縮)
    }                                                           // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void ReductImage88Two()」の【関数名】

「Reduct」は、英単語「reduction」で縮小、
「Image」は、勿論、画像「88」は、16×16升枠で縮小したら8×8升枠に成ります!「Two」は、英単語「Two」、
勿論、数値「2」の事「二番目」です!ここでは、
縮小する時、二番目の値で縮小する事を示します!

(B)関数「void ReductImage88Two()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「ReductImage88Two()」の【仮引数】

void            CopyClear::ReductImage88Two(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){

「TypeArray* ps,」は、S(元)画像情報
「TypeArray* pd」は、D(結果)画像情報

(D)関数「ReductImage88Two()」の【アルゴリズム】

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Two( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (2番目の値で圧縮)
    }                                                           // 
}

(D-1)ローカル変数

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

「BYTE* ptrSX;」は、S画像X座標方向処理ポインタ
「BYTE* ptrDX;」は、D画像X座標方向処理ポインタ
「BYTE* ptrSY;」は、S画像Y座標方向処理ポインタ
「BYTE* ptrDY;」は、D画像Y座標方向処理ポインタ
「int incS;」は、S画像増加幅
「int incD;」は、D画像増加幅
「int h;」は、水平幅(16×16の個数)
「int v;」は、垂直幅(16×16の個数)
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Two( ptrSX, ptrDX, ps->inc, pd->inc );      // 16×16→8×8に縮小
        }                                                       // (2番目の値で圧縮)
    }                                                           // 
}

「h=ps->h/2;h=((h<pd->h)?h:pd->h)/8;」は、SD画像
サイズから水平幅(16×16の個数)算出!
「v=ps->v/2;v=((v<pd->v)?v:pd->v)/8;」は、SD画像
サイズから垂直幅(16×16の個数)算出!
「ptrSY=(BYTE*)ps->adr;ptrDY=(BYTE*)pd->adr;」は、
SD画像の処理ポインタをセット!
「incS=ps->inc16;」は、S画像を16×16升枠単位垂直
増加幅算出!
「incD=pd->inc8;」は、D画像を8×8升枠単位垂直
増加幅算出!
「for(;--v>=0;ptrSY+=incS,ptrDY+=incD){・・外側ループ
本体・・}」は、forループ構文で良くこの解説で紹介
するループ条件「--v>=0;」で垂直個数繰り返し、中身で
垂直方向の処理を行い、ループ後置「ptrSY+=incS,
ptrDY+=incD」でSD両者の垂直方向処理ポインタを進行!
外側ループ本体「ptrSX=ptrSY;ptrDX=ptrDY;」は、SD両者
の水平方向処理ポインタの始点をセット、
「for(i=h;--i>=0;ptrSX+=16,ptrDX+=8){Reduct88Two(
ptrSX,ptrDX,ps->inc,pd->inc);}」は、forループ構文で
内側のループ初期化「i=h;」で一旦ループカウンタをセット
ループ条件「--i>=0;」水平方向繰り返し、中身でサブルー
チン関数「Reduct88Two()」でS画像を16×16升枠単位から
D画像を8×8升枠単位に二番目で縮小します!

(4-14-158)関数「void ReductImage88Three(
TypeArray* ps,TypeArray* pd){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関用画像圧縮(昇順に3番目の値)      *****/
/*****      ☆任意の16×16画素で構成される画像を                *****/
/*****      ☆8×8の基本単位毎に圧縮:3番目☆                    *****/
/************************************************************************/

void            CopyClear::ReductImage88Three(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Three( ptrSX, ptrDX, ps->inc, pd->inc );    // 16×16→8×8に縮小
        }                                                       // (3番目の値で圧縮)
    }                                                           // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void ReductImage88Three()」の【関数名】

「Reduct」は、英単語「reduction」で縮小、
「Image」は、勿論、画像「88」は、16×16升枠で縮小したら8×8升枠に成ります!「Three」は、英単語「Three」、
勿論、数値「3」の事「三番目」です!ここでは、縮小する時、三番目の値で縮小する事を示します!

(B)関数「void ReductImage88Three()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「ReductImage88Three()」の【仮引数】

void            CopyClear::ReductImage88Three(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){

「TypeArray* ps,」は、S(元)画像情報
「TypeArray* pd」は、D(結果)画像情報

(D)関数「ReductImage88Three()」の【アルゴリズム】

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Three( ptrSX, ptrDX, ps->inc, pd->inc );    // 16×16→8×8に縮小
        }                                                       // (3番目の値で圧縮)
    }                                                           // 
}

(D-1)ローカル変数

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

「BYTE* ptrSX;」は、S画像X座標方向処理ポインタ
「BYTE* ptrDX;」は、D画像X座標方向処理ポインタ
「BYTE* ptrSY;」は、S画像Y座標方向処理ポインタ
「BYTE* ptrDY;」は、D画像Y座標方向処理ポインタ
「int incS;」は、S画像増加幅
「int incD;」は、D画像増加幅
「int h;」は、水平幅(16×16の個数)
「int v;」は、垂直幅(16×16の個数)
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Three( ptrSX, ptrDX, ps->inc, pd->inc );    // 16×16→8×8に縮小
        }                                                       // (3番目の値で圧縮)
    }                                                           // 
}

「h=ps->h/2;h=((h<pd->h)?h:pd->h)/8;」は、SD画像
サイズから水平幅(16×16の個数)算出!
「v=ps->v/2;v=((v<pd->v)?v:pd->v)/8;」は、SD画像
サイズから垂直幅(16×16の個数)算出!
「ptrSY=(BYTE*)ps->adr;ptrDY=(BYTE*)pd->adr;」は、
SD画像の処理ポインタをセット!
「incS=ps->inc16;」は、S画像を16×16升枠単位垂直
増加幅算出!
「incD=pd->inc8;」は、D画像を8×8升枠単位垂直
増加幅算出!
「for(;--v>=0;ptrSY+=incS,ptrDY+=incD){・・外側ループ
本体・・}」は、forループ構文で良くこの解説で紹介
するループ条件「--v>=0;」で垂直個数繰り返し、中身で
垂直方向の処理を行い、ループ後置「ptrSY+=incS,
ptrDY+=incD」でSD両者の垂直方向処理ポインタを進行!
外側ループ本体「ptrSX=ptrSY;ptrDX=ptrDY;」は、SD両者
の水平方向処理ポインタの始点をセット、
「for(i=h;--i>=0;ptrSX+=16,ptrDX+=8){Reduct88Three(
ptrSX,ptrDX,ps->inc,pd->inc);}」は、forループ構文で
内側のループ初期化「i=h;」で一旦ループカウンタをセット
ループ条件「--i>=0;」水平方向繰り返し、中身でサブルー
チン関数「Reduct88Three()」でS画像を16×16升枠単位から
D画像を8×8升枠単位に三番目で縮小します!

(4-14-159)関数「void ReductImage88Skip(
TypeArray* ps,TypeArray* pd){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関用画像圧縮(間引き:左上の画素の値)*****/
/*****      ☆任意の16×16画素で構成される画像を                *****/
/*****      ☆8×8の基本単位毎に圧縮:間引き☆                    *****/
/************************************************************************/

void            CopyClear::ReductImage88Skip(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Skip( ptrSX, ptrDX, ps->inc, pd->inc );     // 16×16→8×8に縮小
        }                                                       // (間引き圧縮)
    }                                                           // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void ReductImage88Skip()」の【関数名】

「Reduct」は、英単語「reduction」で縮小、
「Image」は、勿論、画像「88」は、16×16升枠で縮小したら8×8升枠に成ります!「Skip」は、英単語「Skip」、
カタカナ語でスキップ、!ここでは、縮小する時、縮小対象
の元画像≪左上・右上・左下・右下≫の内「左上」を代表と
して縮小する事を示します!★備考★ソースコード上の
サブルーチン関数「Reduct88Skip()」コメントで「右上」と
記載して居るのは記載ミスです!

(B)関数「void ReductImage88Skip()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「ReductImage88Skip()」の【仮引数】

void            CopyClear::ReductImage88Skip(
    TypeArray*  ps,                                             // S配列
    TypeArray*  pd                                              // D配列
){

「TypeArray* ps,」は、S(元)画像情報
「TypeArray* pd」は、D(結果)画像情報

(D)関数「ReductImage88Skip()」の【アルゴリズム】

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Skip( ptrSX, ptrDX, ps->inc, pd->inc );     // 16×16→8×8に縮小
        }                                                       // (間引き圧縮)
    }                                                           // 
}

(D-1)ローカル変数

){
    BYTE*       ptrSX;                                          // S配列:処理ポインタ
    BYTE*       ptrDX;                                          // D配列:処理ポインタ
    BYTE*       ptrSY;                                          // S配列:処理ポインタ
    BYTE*       ptrDY;                                          // D配列:処理ポインタ
    int         incS;                                           // S配列:増加幅(16×16単位)
    int         incD;                                           // D配列:増加幅(8×8単位)
    int         h;                                              // 水平幅(8×8の個数)
    int         v;                                              // 垂直幅(8×8の個数)
    int         i;                                              // カウンタ

「BYTE* ptrSX;」は、S画像X座標方向処理ポインタ
「BYTE* ptrDX;」は、D画像X座標方向処理ポインタ
「BYTE* ptrSY;」は、S画像Y座標方向処理ポインタ
「BYTE* ptrDY;」は、D画像Y座標方向処理ポインタ
「int incS;」は、S画像増加幅
「int incD;」は、D画像増加幅
「int h;」は、水平幅(16×16の個数)
「int v;」は、垂直幅(16×16の個数)
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    h     = ps->h / 2;                                          // 水平個数を
    h     = ( ( h < pd->h ) ? h : pd->h ) / 8;                  // 算出
    v     = ps->v / 2;                                          // 垂直個数を
    v     = ( ( v < pd->v ) ? v : pd->v ) / 8;                  // 算出
    ptrSY = (BYTE*)ps->adr;                                     // S配列:処理ポインタ
    ptrDY = (BYTE*)pd->adr;                                     // D配列:処理ポインタ
    incS  = ps->inc * 16;                                       // S配列:増加幅(16×16単位)
    incD  = pd->inc * 8;                                        // D配列:増加幅(8×8単位)
    for( ; --v >= 0; ptrSY += incS, ptrDY += incD ){            // 垂直個数分
        ptrSX = ptrSY;                                          // S配列:水平始点
        ptrDX = ptrDY;                                          // D配列:水平始点
        for( i = h; --i >= 0; ptrSX += 16, ptrDX += 8 ){        // 水平個数分
            Reduct88Skip( ptrSX, ptrDX, ps->inc, pd->inc );     // 16×16→8×8に縮小
        }                                                       // (間引き圧縮)
    }                                                           // 
}

「h=ps->h/2;h=((h<pd->h)?h:pd->h)/8;」は、SD画像
サイズから水平幅(16×16の個数)算出!
「v=ps->v/2;v=((v<pd->v)?v:pd->v)/8;」は、SD画像
サイズから垂直幅(16×16の個数)算出!
「ptrSY=(BYTE*)ps->adr;ptrDY=(BYTE*)pd->adr;」は、
SD画像の処理ポインタをセット!
「incS=ps->inc16;」は、S画像を16×16升枠単位垂直
増加幅算出!
「incD=pd->inc8;」は、D画像を8×8升枠単位垂直
増加幅算出!
「for(;--v>=0;ptrSY+=incS,ptrDY+=incD){・・外側ループ
本体・・}」は、forループ構文で良くこの解説で紹介
するループ条件「--v>=0;」で垂直個数繰り返し、中身で
垂直方向の処理を行い、ループ後置「ptrSY+=incS,
ptrDY+=incD」でSD両者の垂直方向処理ポインタを進行!
外側ループ本体「ptrSX=ptrSY;ptrDX=ptrDY;」は、SD両者
の水平方向処理ポインタの始点をセット、
「for(i=h;--i>=0;ptrSX+=16,ptrDX+=8){Reduct88Skip(
ptrSX,ptrDX,ps->inc,pd->inc);}」は、forループ構文で
内側のループ初期化「i=h;」で一旦ループカウンタをセット
ループ条件「--i>=0;」水平方向繰り返し、中身でサブルー
チン関数「Reduct88Skip()」でS画像を16×16升枠単位から
D画像を8×8升枠単位に縮小します!

(4-14-160)関数「void GetHVReductImage88(
TypeArray* ps,TypeArray* pd){・・・}」

/************************************************************************/
/*****      8×8画素正規化相関用画像圧縮(平均値)用縦横個数取得  *****/
/************************************************************************/

void            CopyClear::GetHVReductImage88(
    TypeArray*  ps,                                     // S配列
    TypeArray*  pd,                                     // D配列
    int&        resH,                                   // 取得する水平個数
    int&        resV                                    // 取得する垂直個数
){
    resH = ps->h / 2;                                   // 水平個数を
    resH = ( ( resH < pd->h ) ? resH : pd->h ) / 8;     // 算出
    resV = ps->v / 2;                                   // 垂直個数を
    resV = ( ( resV < pd->v ) ? resV : pd->v ) / 8;     // 算出
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void GetHVReductImage88()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Reduct」は、英単語「reduction」で縮小、
「Image」は、勿論、画像「88」は、16×16升枠で縮小したら8×8升枠に成ります!
仮引数「int &resH,int &resV」の値を算出する事で
事前にバッファー取得の予備に使用します!

(B)関数「void GetHVReductImage88()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVReductImage88()」の【仮引数】

void            CopyClear::GetHVReductImage88(
    TypeArray*  ps,                                     // S配列
    TypeArray*  pd,                                     // D配列
    int&        resH,                                   // 取得する水平個数
    int&        resV                                    // 取得する垂直個数
){

「TypeArray* ps,」は、S(元)画像情報
「TypeArray* pd」は、D(結果)画像情報
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「GetHVReductImage88()」の【アルゴリズム】

){
    resH = ps->h / 2;                                   // 水平個数を
    resH = ( ( resH < pd->h ) ? resH : pd->h ) / 8;     // 算出
    resV = ps->v / 2;                                   // 垂直個数を
    resV = ( ( resV < pd->v ) ? resV : pd->v ) / 8;     // 算出
}

「resH=ps->h/2;resH=((resH<pd->h)?resH:pd->h)/8;」は、
8×8升枠の水平方向個数を算出し引数辺値で返す!
「resV=ps->v/2;resV=((resV<pd->v)?resV:pd->v)/8;」は、
8×8升枠の垂直方向個数を算出し引数辺値で返す!

(4-14-161)関数「void VectorCorrImage88(
TypeArray* pa,
TypeArray* pb,
double* bufVecX,
double* bufVecY,int nOffsetH,
int nOffsetV,int nStepH,
int nStepV,int& resH,int& resV){・・・}」

/****************************************************************************/
/*****      8×8画素正規化相関を使用した動線ベクトル算出              *****/
/****************************************************************************/

void            CopyClear::VectorCorrImage88(
    TypeArray*  pa,                                         // A配列
    TypeArray*  pb,                                         // B配列
    double*     bufVecX,                                    // X方向結果バッファー
    double*     bufVecY,                                    // Y方向結果バッファー
    int         nOffsetH,                                   // 水平方向オフセット(左右ずれ)
    int         nOffsetV,                                   // 垂直方向オフセット(上下ずれ)
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    BYTE*       ptrBX;                                      // B配列:処理ポインタ
    BYTE*       ptrBY;                                      // B配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         incB;                                       // B配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         HV;                                         // 水平/垂直幅の有効幅
    int         i;                                          // カウンタ

    HV    = ( pa->h < pb->h ) ? pa->h : pb->h;              // 水平幅最小値算出
    HV    = HV - ( 8 + nOffsetH * 2 );                      // 水平幅の有効幅算出
    h     = HV / nStepH;                                    // 水平個数を算出
    HV    = ( pa->v < pb->v ) ? pa->v : pb->v;              // 垂直幅最小値算出
    HV    = HV - ( 8 + nOffsetV * 2 );                      // 垂直幅の有効幅算出
    v     = HV / nStepV;                                    // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr + nOffsetH + nOffsetV * pa->inc; // A配列:始点処理ポインタ
    ptrBY = (BYTE*)pb->adr + nOffsetH + nOffsetV * pb->inc; // B配列:始点処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                               // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){        // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        ptrBX = ptrBY;                                      // B配列:水平始点
        for( i = h; --i >= 0; ){                            // 水平個数分
            VectorCorr88( ptrAX, ptrBX,                     // 
                    pa->inc, pb->inc, nOffsetH, nOffsetV,   // 
                    bufVecX, bufVecY );                     // 
            bufVecX++;                                      // 格納ポインタ次点移動
            bufVecY++;                                      // 格納ポインタ次点移動
            ptrAX += nStepH;                                // A配列:次点移動
            ptrBX += nStepH;                                // B配列:次点移動
        }                                                   // 
    }                                                       // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void VectorCorrImage88()」の【関数名】

「Vector」は、英単語「vector」、カタカナ語「ベクター・
ベクトル」で、数学的には「方向量」と向きと大きさを意味
「Corr」は、カタカナ語「コア」で物事の中心を意味!
「Image」は、勿論、画像
「88」は、8×8升枠を意味します!
ここでは、8×8升枠のAB二画像比較するコア操作です!

(B)関数「void VectorCorrImage88()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「VectorCorrImage88()」の【仮引数】

void            CopyClear::VectorCorrImage88(
    TypeArray*  pa,                                         // A配列
    TypeArray*  pb,                                         // B配列
    double*     bufVecX,                                    // X方向結果バッファー
    double*     bufVecY,                                    // Y方向結果バッファー
    int         nOffsetH,                                   // 水平方向オフセット(左右ずれ)
    int         nOffsetV,                                   // 垂直方向オフセット(上下ずれ)
    int         nStepH,                                     // 水平方向次点ステップ数
    int         nStepV,                                     // 垂直方向次点ステップ数
    int&        resH,                                       // 返値:取得する水平個数
    int&        resV                                        // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「double* bufVecX,」は、ベクターのX座標成分バッファー
「double* bufVecY,」は、ベクターのY座標成分バッファー
「int nOffsetH,」は、水平方向オフセット
「int nOffsetV,」は、垂直方向オフセット
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「VectorCorrImage88()」の【アルゴリズム】

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    BYTE*       ptrBX;                                      // B配列:処理ポインタ
    BYTE*       ptrBY;                                      // B配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         incB;                                       // B配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         HV;                                         // 水平/垂直幅の有効幅
    int         i;                                          // カウンタ

    HV    = ( pa->h < pb->h ) ? pa->h : pb->h;              // 水平幅最小値算出
    HV    = HV - ( 8 + nOffsetH * 2 );                      // 水平幅の有効幅算出
    h     = HV / nStepH;                                    // 水平個数を算出
    HV    = ( pa->v < pb->v ) ? pa->v : pb->v;              // 垂直幅最小値算出
    HV    = HV - ( 8 + nOffsetV * 2 );                      // 垂直幅の有効幅算出
    v     = HV / nStepV;                                    // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr + nOffsetH + nOffsetV * pa->inc; // A配列:始点処理ポインタ
    ptrBY = (BYTE*)pb->adr + nOffsetH + nOffsetV * pb->inc; // B配列:始点処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                               // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){        // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        ptrBX = ptrBY;                                      // B配列:水平始点
        for( i = h; --i >= 0; ){                            // 水平個数分
            VectorCorr88( ptrAX, ptrBX,                     // 
                    pa->inc, pb->inc, nOffsetH, nOffsetV,   // 
                    bufVecX, bufVecY );                     // 
            bufVecX++;                                      // 格納ポインタ次点移動
            bufVecY++;                                      // 格納ポインタ次点移動
            ptrAX += nStepH;                                // A配列:次点移動
            ptrBX += nStepH;                                // B配列:次点移動
        }                                                   // 
    }                                                       // 
}

(D-1)ローカル変数

){
    BYTE*       ptrAX;                                      // A配列:処理ポインタ
    BYTE*       ptrAY;                                      // A配列:処理ポインタ
    BYTE*       ptrBX;                                      // B配列:処理ポインタ
    BYTE*       ptrBY;                                      // B配列:処理ポインタ
    int         incA;                                       // A配列:増加幅(nStepV単位)
    int         incB;                                       // B配列:増加幅(nStepV単位)
    int         h;                                          // 水平幅(8×8の個数)
    int         v;                                          // 垂直幅(8×8の個数)
    int         HV;                                         // 水平/垂直幅の有効幅
    int         i;                                          // カウンタ

「BYTE* ptrAX;」は、A画像X座標方向処理ポインタ
「BYTE* ptrBX;」は、B画像X座標方向処理ポインタ
「BYTE* ptrAY;」は、A画像Y座標方向処理ポインタ
「BYTE* ptrBY;」は、B画像Y座標方向処理ポインタ
「int incA;」は、A画像増加幅
「int incB;」は、B画像増加幅
「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
「int HV;」は、水平垂直幅算出用の計算途中置き場
「int i;」は、ループカウンタ

(D-2)アルゴリズムコード

    HV    = ( pa->h < pb->h ) ? pa->h : pb->h;              // 水平幅最小値算出
    HV    = HV - ( 8 + nOffsetH * 2 );                      // 水平幅の有効幅算出
    h     = HV / nStepH;                                    // 水平個数を算出
    HV    = ( pa->v < pb->v ) ? pa->v : pb->v;              // 垂直幅最小値算出
    HV    = HV - ( 8 + nOffsetV * 2 );                      // 垂直幅の有効幅算出
    v     = HV / nStepV;                                    // 垂直個数を算出
    resH  = h;                                              // 返値:水平個数
    resV  = v;                                              // 返値:垂直個数
    ptrAY = (BYTE*)pa->adr + nOffsetH + nOffsetV * pa->inc; // A配列:始点処理ポインタ
    ptrBY = (BYTE*)pb->adr + nOffsetH + nOffsetV * pb->inc; // B配列:始点処理ポインタ
    incA  = pa->inc * nStepV;                               // A配列:増加幅(nStepV単位)
    incB  = pb->inc * nStepV;                               // B配列:増加幅(nStepV単位)
    for( ; --v >= 0; ptrAY += incA, ptrBY += incB ){        // 垂直個数分
        ptrAX = ptrAY;                                      // A配列:水平始点
        ptrBX = ptrBY;                                      // B配列:水平始点
        for( i = h; --i >= 0; ){                            // 水平個数分
            VectorCorr88( ptrAX, ptrBX,                     // 
                    pa->inc, pb->inc, nOffsetH, nOffsetV,   // 
                    bufVecX, bufVecY );                     // 
            bufVecX++;                                      // 格納ポインタ次点移動
            bufVecY++;                                      // 格納ポインタ次点移動
            ptrAX += nStepH;                                // A配列:次点移動
            ptrBX += nStepH;                                // B配列:次点移動
        }                                                   // 
    }                                                       // 
}

「HV=(pa->h<pb->h)?pa->h:pb->h;
HV=HV-(8+nOffsetH2);」は、水平方向の実効長さ算出し、
「h=HV/nStepH;」で8×8升枠水平方向個数算出!
「HV=(pa->v<pb->v)?pa->v:pb->v;
HV=HV-(8+nOffsetV2);」は、垂直方向の実効長さ算出し、
「v=HV/nStepV;」で8×8升枠垂直方向個数算出!
「resH=h;resV=v;」は、仮引数「int& resH,int& resV」へ
引数辺値を返す!
「ptrAY=(BYTE*)pa->adr+nOffsetH+nOffsetVpa->inc;」は
A画像Y座標方向処理ポインタ処理始点セット!
「ptrBY=(BYTE)pb->adr+nOffsetH+nOffsetVpb->inc;」は
B画像Y座標方向処理ポインタ処理始点セット!
「incA=pa->incnStepV;incB=pb->inc*nStepV;」は、
A画像・B画像の8×8升枠垂直方向増加幅を算出しセット
「for(;--v>=0;ptrAY+=incA,ptrBY+=incB){・・外側ループ
中身・・}」とforループ構文で良くこの解説で紹介する
ループ条件「--v>=0;」で垂直個数繰り返し、中身で垂直
方向の処理を行い、ループ後置「ptrAY+=incA,ptrBY+=incB」
でAB両者の垂直方向処理ポインタを進行!外側ループ本体
「ptrAX=ptrAY;ptrBX=ptrBY;」は、A画像・B画像のX座標
方向処理ポインタ処理始点セット!
「for(i=h;--i>=0;){・・内側ループ中身・・}」は、
ループ初期化「i=h;」でループカウンタに水平方向個数を
セットし、forループ構文で良くこの解説で紹介する
ループ条件「--i>=0;」で水平個数繰り返し、中身は、まず
「VectorCorr88(ptrAX,ptrBX,pa->inc,pb->inc,nOffsetH,
nOffsetV,bufVecX,bufVecY);」でサブルーチン関数「
VectorCorr88()」で8×8升枠い1単位処理し、
「bufVecX++;bufVecY++;」で算出したベクターX座標成分
Y座標成分バッファー格納ポインタを進める!
「ptrAX+=nStepH;ptrBX+=nStepH;」は、AB両者の水平方
向処理ポインタを進行!

(4-14-162)関数「void GetHVVectorCorrImage88(
TypeArray* pa,TypeArray* pb,
int nOffsetH,int nOffsetV,
int nStepH,int nStepV,
int& resH,int& resV){・・・}」

/********************************************************************************/
/*****      8×8画素正規化相関を使用した動線ベクトル算出用升目個数取得    *****/
/********************************************************************************/

void            CopyClear::GetHVVectorCorrImage88(
    TypeArray*  pa,                                     // A配列
    TypeArray*  pb,                                     // B配列
    int         nOffsetH,                               // 水平方向オフセット(左右ずれ)
    int         nOffsetV,                               // 垂直方向オフセット(上下ずれ)
    int         nStepH,                                 // 水平方向次点ステップ数
    int         nStepV,                                 // 垂直方向次点ステップ数
    int&        resH,                                   // 返値:取得する水平個数
    int&        resV                                    // 返値:取得する垂直個数
){
    int         h;                                      // 水平幅(8×8の個数)
    int         v;                                      // 垂直幅(8×8の個数)
    int         HV;                                     // 水平/垂直幅の有効幅

    HV   = ( pa->h < pb->h ) ? pa->h : pb->h;           // 水平幅最小値算出
    HV   = HV - ( 8 + nOffsetH * 2 );                   // 水平幅の有効幅算出
    h    = HV / nStepH;                                 // 水平個数を算出
    HV   = ( pa->v < pb->v ) ? pa->v : pb->v;           // 垂直幅最小値算出
    HV   = HV - ( 8 + nOffsetV * 2 );                   // 垂直幅の有効幅算出
    v    = HV / nStepV;                                 // 垂直個数を算出
    resH = h;                                           // 返値:水平個数
    resV = v;                                           // 返値:垂直個数
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!

(A)関数「void GetHVVectorCorrImage88()」の【関数名】

「Get」は、カタカナ語でもゲット、詰り取得するで
「HV」は、水平・垂直方向の個数を意味します!
「Vector」は、英単語「vector」、カタカナ語「ベクター・
ベクトル」で、数学的には「方向量」と向きと大きさを意味
「Corr」は、カタカナ語「コア」で物事の中心を意味!
「Image」は、勿論、画像
「88」は、8×8升枠を意味します!
ここでは、8×8升枠のAB二画像比較するコア操作です!

(B)関数「void GetHVVectorCorrImage88()」の【返値】

関数返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「GetHVVectorCorrImage88()」の【仮引数】

void            CopyClear::GetHVVectorCorrImage88(
    TypeArray*  pa,                                     // A配列
    TypeArray*  pb,                                     // B配列
    int         nOffsetH,                               // 水平方向オフセット(左右ずれ)
    int         nOffsetV,                               // 垂直方向オフセット(上下ずれ)
    int         nStepH,                                 // 水平方向次点ステップ数
    int         nStepV,                                 // 垂直方向次点ステップ数
    int&        resH,                                   // 返値:取得する水平個数
    int&        resV                                    // 返値:取得する垂直個数
){

「TypeArray* pa,」は、比較対象画像A
「TypeArray* pb,」は、比較対象画像B
「int nOffsetH,」は、水平方向オフセット
「int nOffsetV,」は、垂直方向オフセット
「int nStepH,」は、比較8×8升枠移動水平方向ステップ
「int nStepV,」は、比較8×8升枠移動垂直方向ステップ
「int& resH,」は、水平方向の結果個数
「int& resV」は、垂直方向の結果個数

(D)関数「GetHVVectorCorrImage88()」の【アルゴリズム】

){
    int         h;                                      // 水平幅(8×8の個数)
    int         v;                                      // 垂直幅(8×8の個数)
    int         HV;                                     // 水平/垂直幅の有効幅

    HV   = ( pa->h < pb->h ) ? pa->h : pb->h;           // 水平幅最小値算出
    HV   = HV - ( 8 + nOffsetH * 2 );                   // 水平幅の有効幅算出
    h    = HV / nStepH;                                 // 水平個数を算出
    HV   = ( pa->v < pb->v ) ? pa->v : pb->v;           // 垂直幅最小値算出
    HV   = HV - ( 8 + nOffsetV * 2 );                   // 垂直幅の有効幅算出
    v    = HV / nStepV;                                 // 垂直個数を算出
    resH = h;                                           // 返値:水平個数
    resV = v;                                           // 返値:垂直個数
}

(D-1)ローカル変数

){
    int         h;                                      // 水平幅(8×8の個数)
    int         v;                                      // 垂直幅(8×8の個数)
    int         HV;                                     // 水平/垂直幅の有効幅

「int h;」は、水平幅(8×8の個数)
「int v;」は、垂直幅(8×8の個数)
「int HV;」は、水平垂直幅算出用の計算途中置き場

(D-2)アルゴリズムコード

    HV   = ( pa->h < pb->h ) ? pa->h : pb->h;           // 水平幅最小値算出
    HV   = HV - ( 8 + nOffsetH * 2 );                   // 水平幅の有効幅算出
    h    = HV / nStepH;                                 // 水平個数を算出
    HV   = ( pa->v < pb->v ) ? pa->v : pb->v;           // 垂直幅最小値算出
    HV   = HV - ( 8 + nOffsetV * 2 );                   // 垂直幅の有効幅算出
    v    = HV / nStepV;                                 // 垂直個数を算出
    resH = h;                                           // 返値:水平個数
    resV = v;                                           // 返値:垂直個数
}

「HV=(pa->h<pb->h)?pa->h:pb->h;
HV=HV-(8+nOffsetH2);」は、水平方向の実効長さ算出し、
「h=HV/nStepH;」で8×8升枠水平方向個数算出!
「HV=(pa->v<pb->v)?pa->v:pb->v;
HV=HV-(8+nOffsetV2);」は、垂直方向の実効長さ算出し、
「v=HV/nStepV;」で8×8升枠垂直方向個数算出!
「resH=h;resV=v;」は、仮引数「int& resH,int& resV」へ
引数辺値を返す!

(4-14-163)関数「double AverageImage88XY(TypeArray* pa,int x,int y){・・・}

/************************************************************************************/
/*****      8×8画素画像平均適応:個別                                        *****/
/*****      ☆8×8の基本単位毎に指定された場所の画像を演算しバッファーに格納☆*****/
/************************************************************************************/

double          CopyClear::AverageImage88XY(
    TypeArray*  pa,                                                 // A配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

    minH = pa->h - 8;                                               // 水平幅の有効範囲算出
    minV = pa->v - 8;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Ave8M( ptrA + x + y * incA, incA, 8 ) );            // 8×8画素平均算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0を返す
    }                                                               // 
}

☆備考☆この関数はファイル「CopyClear400.cpp」に存在!
★注意★この関数は「public:」属性ですのでライブラリの
外から使用可能です!
★注意★この関数には、同名で仮引数が異なるオーバーロー
ド(多重定義)関数が存在します!

(A)関数「AverageImage88XY()」の【関数名】

「Average」は、英単語「Average」で「平均値」を意味
「Image」は、勿論、画像です!
「88」は、処理する画像の範囲として「縦×横=4×4=
16画素」のサイズを意味します
「XY」は、XY座標を意味します!詰り、画像の中でXY
座標を指定した場所の8×8升枠の平均値算出関数です!

(B)関数「double AverageImage88XY()」の【返値】

関数返値として算出した平均値を返す関数です!

(C)関数「AverageImage88XY()」の【仮引数】

double          CopyClear::AverageImage88XY(
    TypeArray*  pa,                                                 // A配列
    int         x,                                                  // X座標値
    int         y                                                   // Y座標値
){

「TypeArray* pa,」は、画像情報
「int x」は、X座標
「int y」は、Y座標

(D)関数「AverageImage88XY()」の【アルゴリズム】

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

    minH = pa->h - 8;                                               // 水平幅の有効範囲算出
    minV = pa->v - 8;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Ave8M( ptrA + x + y * incA, incA, 8 ) );            // 8×8画素平均算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0を返す
    }                                                               // 
}

(D-1)ローカル変数

){
    BYTE*       ptrA;                                               // A配列:処理ポインタ
    int         incA;                                               // A配列:増加幅
    int         minH;                                               // Aの有効水平幅
    int         minV;                                               // Aの有効垂直幅

「BYTE* ptrA;」は、画素単位処理ポインタ
「int incA;」は、増加幅★備考★「int inc;」の方が相応
しいと思われるでしょう、この記載に成ったのは、単に
コピペで他の部分から流用したからです!同じ様に処理ポイ
ンタも「BYTE* ptr;」の方が相応しいが、同じ理由から、
この変数名に成ったのです!
「int minH;」は、水平幅の有効(8×8升枠を考慮)幅
「int minV;」は、垂直幅の有効(8×8升枠を考慮)幅

(D-2)アルゴリズムコード

    minH = pa->h - 8;                                               // 水平幅の有効範囲算出
    minV = pa->v - 8;                                               // 垂直幅の有効範囲算出
    ptrA = (BYTE*)pa->adr;                                          // A配列:処理ポインタ
    incA = pa->inc;                                                 // A配列:増加幅
    if( x >= 0 && x < minH && y >= 0 && y < minV ){                 // 有効範囲内ならば
        return( Ave8M( ptrA + x + y * incA, incA, 8 ) );            // 8×8画素平均算出
    }else{                                                          // 範囲外ならば
        return( 0.0 );                                              // 0.0を返す
    }                                                               // 
}

「minH=pa->h-8;」は、水平有効幅算出
「minV=pa->v-8;」は、垂直有効幅算出
「ptrA=(BYTE*)pa->adr;」は、処理ポインタのセット
「incA=pa->inc;」は、増加幅のセット
「if(x>=0&&x<minH&&y>=0&&y<minV){・・成立中身・・}」
は、条件「x>=0&&x<minH&&y>=0&&y<minV」で有効サイズで「8×8」升枠が、XY座標設定時に有効な場合、成立
「return(Ave8M(ptrA+x+yincA,incA,8));」とサブルーチン関数「Ave8M(ptrA+x+yincA,incA,8));」で処理し関数終了!
不成立「else{return(0.0);}」で関数辺値として「0.0」を
返し関数終了!

本日(2月4)の講義はココまでとします!まだ、
正規化相関系のpublics関数の説明は終わっていません!
※編集追加時に赤字「下書きの保存に失敗」と
noteエディタが忠告を出したので
この続きは、解説『クラスCopyClear(24)』
続きます!!引き続き御贔屓をお願いします!

文末

いいなと思ったら応援しよう!