0

次の関数を使用して、特定の行列の位置が中心にどれだけ近いかに応じて、0〜1の値の重み行列を返します。また、しきい値の後、値はすべて1になります(中心に近いポイントが値1を持ち、距離のしきい値がエッジで1から0に直線的に下がった後、中心から離れたポイントを持つプラトーのようなものです)?

cv::Mat2f getWeightsMatrix(int N, int M, float r){
    cv::Mat2f weights = cv::Mat2f(N,M);
    int i,j;
    for(i=0;i<N;i++){
        for(j=0;j<M;j++){
            if(i<=floor(N*(1-r)/2)){
                if(j<=floor(M*(1-r)/2)){
                    weights[i][j]=((float)(i/N-j/M)/(1-r));
                }
                else{
                    weights[i][j]=(2*(float)(i/N)/(1-r));
                }
            }
            else if (i>=floor(N*(1+r)/2)){
                if(j>=floor(M*(1+r)/2)){
                    weights[i][j]=(((float)((N-i)/N))-((float)((M-j)/M)))/(1-r);
                }
                else{
                    weights[i][j]=(2*(float)((N-i)/N)/(1-r));
                }
            }
            else{
                if(j<=floor(M*(1-r)/2)){
                    weights[i][j]=(2*(float)(j/M)/(1-r));
                }
                else if(j>=floor(M*(1+r)/2)){
                    weights[i][j]=(2*(float)((M-j)/M)/(1-r));
                }
                else{
                    weights[i][j]=1;
                }
            }
        }
    }
    cout << weights << endl;
    return weights;
}

今私の問題は、いくつかのキャストの問題があり、値0と1のみが返されることです(フロートはありません)。また、N = 10、M = 10、r = 0.5で関数を呼び出すと、coutによって表示される行列サイズは20x10になります。

助けてください!

編集:これは出力です

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
4

1 に答える 1

4

整数に対して基本的な操作を行うと、結果が自動的に丸められるため、行列は整数の場合にのみ構成されます。

例:あなたが書くとき

weights[i][j]=((float)(i/N-j/M)/(1-r));

の結果はi/N整数に丸められ、整数にj/Mも丸められ、最後に、による除算(1-r)も丸められます。あなたの(float)キャストは良い考えですが、適用が遅すぎます。

あなたはいくつかのことをすることができます:

  • たとえば、float(i)/N代わりに基本操作の内部にキャストしますi/N
  • 整数の代わりに浮動小数点数を使用します。1.0代わりに書き込みます1
  • ループとステートメント内でフロートを使用する

例えば:

for(float i = 0; i < N-0.5; i++) {
    for(float j = 0; j < M-0.5; j++) {
        if(i <= floor(N*(1.0-r)/2.0)) {
            // ...

浮動小数点の精度のために、などのテストがi < N合格する場合と合格しない場合があることを理解することが重要ですfloat i = N0.5これが、ループの境界Nとを差し引くことでちょっとしたトリックをした理由ですM

于 2012-10-23T15:07:15.380 に答える