matlab रोटेशन के प्रक्षेपण को उलटा



image-processing matrix (1)

मैंने आपके P1.csv 750x1000 मैट्रिक्स पर सी + + में छोटा परीक्षण किया था। मैट्रिक्स केंद्र के आसपास द्विरेखीय प्रक्षेप के साथ -10deg फिर 10- -10deg मैंने इसे घुमाया।

परिणामी संबंध (परिणाम के 749x749 9 749x749 9 मध्य वर्ग पर) 749x749 9 0.8275936 तो या तो आप एक ही डेटा (शायद कुछ मैट्रिक्स के बीच ऑफसेट) से संबंध नहीं कर रहे हैं या आप परिणाम को किसी तरह छूटे हुए हैं उदाहरण के लिए, मैं इसे अपने पूर्णांक मैट्रिक्स रोटेशन कोड से बना देता हूं और जब आप सहसंबंध को कम करके पूर्णांक को हटाना भूल जाते हैं तो आपके दावों के समान है 0.3

जैसा कि मैंने अपने सी ++ स्रोत पर Matlab का उपयोग नहीं किया है, आप पोर्ट की कोशिश कर सकते हैं या अपने कार्यान्वयन से जांच कर सकते हैं:

//---------------------------------------------------------------------------
const float deg=M_PI/180.0;
const float rad=180.0/M_PI;
int x0,y0,r0; 
matrix A,B,C;
float c=0.0,ang=10.0*deg;
//---------------------------------------------------------------------------
void rotcw(matrix &B,matrix &A,int x0,int y0,float ang) // rotate A -> B by angle ang around (x0,y0) CW if ang>0
    {
    int x,y,ix0,iy0,ix1,iy1;
    float xx,yy,fx,fy,c,s,q;
    B.resize(A.xs,A.ys);
    // circle kernel
    c=cos(-ang); s=sin(-ang);
    // rotate
    for (y=0;y<A.ys;y++)
     for (x=0;x<A.xs;x++)
        {
        // offset so (0,0) is center of rotation
        xx=x-x0;
        yy=y-y0;
        // rotate (fx,fy) by ang
        fx=float((xx*c)-(yy*s));
        fy=float((xx*s)+(yy*c));
        // offset back and convert to ints and weights
        fx+=x0; ix0=floor(fx); fx-=ix0; ix1=ix0+1; if (ix1>=A.xs) ix1=ix0;
        fy+=y0; iy0=floor(fy); fy-=iy0; iy1=iy0+1; if (iy1>=A.ys) iy1=iy0;
        // bilinear interpolation A[fx][fy] -> B[x][y]
        if ((ix0>=0)&&(ix0<A.xs)&&(iy0>=0)&&(iy0<A.ys))
            {
            xx=float(A[ix0][iy0])+(float(A[ix1][iy0]-A[ix0][iy0])*fx);
            yy=float(A[ix0][iy1])+(float(A[ix1][iy1]-A[ix0][iy1])*fx);
            xx=xx+((yy-xx)*fy); q=xx;
            } else q=0;
        B[x][y]=q;
        }
    }
//---------------------------------------------------------------------------
float correl(matrix &A,matrix &B,int x0,int y0,int x1,int y1)
    {
    int x,y;
    float sxy=0.0,sx=0.0,sy=0.0,sxx=0.0,syy=0.0,n=(x1-x0+1)*(y1-y0+1),a,b;
    for (x=x0;x<=x1;x++)
     for (y=y0;y<=y1;y++)
        {
        a=A[x][y];
        b=B[x][y];
        sx+=a; sxx+=a*a;
        sy+=b; syy+=b*b;
        sxy+=a*b;
        }
    a=(n*sxy)-(sx*sy);
    b=sqrt((n*sxx)-(sx*sx))*sqrt((n*syy)-(sy*sy));
    if (fabs(b)<1e-10) return 0.0;
    return a/b;
    }
//---------------------------------------------------------------------------

matrix A सिर्फ गतिशील 2 डी सरणी है (मुझे इसके लिए पर्दाफाश किया गया है) जैसे float A[A.xs][A.ys]; जहां xs,ys आकार है A.resize(xs,ys) मैट्रिक्स A से नए आकार का आकार बदल देगा। यहां स्रोत:

//---------------------------------------------------------------------------
class matrix
    {
public:
    int xs,ys;
    float **a;  // float a[xs][ys]

    matrix()    { a=NULL; xs=0; ys=0; }
    matrix(matrix& q)   { *this=q; }
    ~matrix()   { free(); }
    matrix* operator = (const matrix *q) { *this=*q; return this; }
    matrix* operator = (const matrix &q) { resize(q.xs,q.ys); for (int x=0;x<xs;x++) for (int y=0;y<ys;y++)  a[x][y]=q.a[x][y]; return this; }
    float* operator[] (int x) { return a[x]; };

    void free() { if (a) { if (a[0]) delete[] a[0]; delete[] a; } a=NULL; xs=0; ys=0; }
    void resize(int _xs,int _ys)
        {
        free();
        if (_xs<=0) return;
        if (_ys<=0) return;
        a=new float*[_xs]; if (a==NULL) return;
        float *aa=new float[_xs*_ys];   if (aa==NULL) return;
        xs=_xs; ys=_ys;
        for (int x=0;x<xs;x++,aa+=ys) a[x]=aa;
        }
    };
//---------------------------------------------------------------------------

परीक्षण इस तरह दिखता है:

x0=A.xs>>1; // center for rotation
y0=A.ys>>1;
if (x0<y0) r0=x0-1; else r0=y0-1; // mid square size for correltaion
rotcw(B,A,x0,y0,+ang);
rotcw(C,B,x0,y0,-ang);
c=correl(A,C,x0-r0,y0-r0,x0+r0,y0+r0);

द्विरेखीय प्रक्षेप के कारण घूमने वाले कोशिकाओं को पड़ोसी कोशिकाओं में खून बह रहा है, इसलिए यदि आपको कई बार घूमने की आवश्यकता होती है (उदाहरण के लिए अज्ञात कोण पता लगाना), तो आपको हमेशा उप-परिणाम मैट्रिक्स पर रोटेशन को कई बार लागू करने के बजाय मूल मैट्रिक्स को घुमाने के लिए चाहिए।

आपके पी 1 के लिए यहां पूर्वावलोकन

बाईं ओर मूल मैट्रिक्स A में बीच में घुमाए गए मैट्रिक्स B +10deg CW और सही मैट्रिक्स C पर -10deg CW द्वारा वापस घुमाया गया। ब्लू पिक्सल सकारात्मक हैं और लाल पिक्सल नकारात्मक मान हैं I हरे रंग का आयत सहसंबद्ध क्षेत्र (वर्ग ओवरलैप क्षेत्र का एसक्यूआरटी)

[संपादन 1] मैं थोड़ा रंग भरकर खेलता हूं

चलो a0=-13.487; a1=9.3039; a0=-13.487; a1=9.3039; आपके A मैट्रिक्स से न्यूनतम और अधिकतम मान हो उसके बाद आर, जीबी रंग की किसी भी मूल्य से A,B या C से गणना करने के लिए मैंने इसका इस्तेमाल किया:

DWORD col(float x)
    {
    DWORD c; int sh;
    if (x>=0) { sh= 0; x/=a1; } // positive values in Blue
    else      { sh=16; x/=a0; } // negative values in Red
    x*=255.0*50.0; // 50.0x saturated to emphasize used values
    c=x; if (c>255) c=255; // clamp to 8bit per channel
    return c<<sh;
    }

और यहां के पुनरावर्ती परिणाम:

जैसा कि आप देख सकते हैं कि ऐसी विशेषताएं हैं जो बूथ को रोटेशन कोण और रोटेशन के केंद्र का पता लगाने के लिए इस्तेमाल की जा सकती हैं ... बस A / B में छेद खोजें / फिर अंतर के कोण की गणना करें। रोटेशन के ऑफसेट को ऑफसेट करने के बाद और आपको सभी की ज़रूरत होनी चाहिए ...

किसी प्रोजेक्ट के लिए, मेरे पास एक matrix<float> जो कुछ डिग्री घूमता है। इस प्रक्रिया पर मेरा कोई नियंत्रण नहीं है (मानिए कि यह निकटतम पड़ोसी का उपयोग कर रहा है), मैं इस रोटेशन ऑपरेशन को रिवर्स करना चाहता हूं और प्रारंभिक मैट्रिक्स प्राप्त करना चाहता हूँ।

मेरी शुरुआती धारणा थी कि मैं घूमने वाले मैट्रिक्स को मध्य-भाग के साथ घुमाएगा और मध्य भाग को फसल देगा, मेरे पास मूल मैट्रिक्स होगा लेकिन परिणाम बताते हैं कि गुणवत्ता नाटकीय रूप से घिस जाती है।

मेरे मूल मैट्रिक्स ( चित्रा की पहली छवि ) 10x10 मैट्रिक्स 1 से 100 पर गौर करें। मैं इसे 10 डिग्री, फिर -10 डिग्री में घुमाएगा। चित्रा में दूसरी छवि मेरे परिणामस्वरूप मैट्रिक्स है। फिर मैं दूसरी मैट्रिक्स के बीच से फसल खाती हूँ और इसे प्रारंभिक मैट्रिक्स के साथ सहसंबंधी बना देता हूं।

मैंने 1000 * 1000 के 1000 यादृच्छिक मैट्रिक्स के साथ इस परीक्षण किया; जब मैं घूमता -10 डिग्री bicubic या bilinear प्रक्षेप के साथ, औसत सहसंबंध परिणाम लगभग 0.37 होता है जबकि nearest neighbor 0.25 है।

यदि दोनों द्विपदीय या bicubic , तो सहसंबंध परिणाम लगभग 0.45-0.5 है।

मैं सोच रहा हूं कि प्रक्षेप के कारण होने वाले नुकसान को कम करने का कोई तरीका है ध्यान दें कि वास्तविक प्रयोग में मेरे पास मूल छवि नहीं है, मैं सिर्फ रोटेशन कोण का अनुमान लगा रहा हूं, इसलिए रोटेशन कोण अनुमान की शुद्धता के कारण अन्य प्रदर्शन ड्रॉप है। मैंने ऑनलाइन खोज की लेकिन इसके बारे में कुछ भी नहीं मिला।

यहां मैटैब में मेरा सरल परीक्षण कोड है,

res = 0;
for i = 0:1000
    a = uint8(rand(1000,1000)*255);
    arr = imrotate(imrotate(a,10, 'bicubic'), -10, 'bicubic');

    [r1,c1] = size(a);
    [r2,c2] = size(arr);
    rd = ceil((c2-c1)/2);
    cd = ceil((r2-r1)/2);
    c_arr = arr(cd:end-cd, rd:end-rd);

    res = res+corr2(a, c_arr);
end
res/1000




interpolation