2016-04-13 9 views
1

bir döngü için kullanmadan (hatta her iki x ve y endeksleri) da endeks değerleri almak istiyor aşağıdaki matrisOpenCV, C++ kullanarak çift/tek indekslerdeki değerler nasıl zarif bir şekilde alınır?

0 1 2 3 
4 5 6 7 
8 9 10 11 
12 13 14 15 

sahip düşünün.

0 2 
8 10 

Büyük boyutlu resimlerim var (çoğu 5000 * 5000 + gri tonlamalı matris). For döngüsü kullanmak en iyi yol gibi görünmüyor. Döngüden daha iyi bir yol olup olmadığını duymak isterim.

Aşağıdaki maske kullanarak çalıştı

ardından işlemleri yapmak ama^2 4 * n^2 çarpma ziyade n yapmak gerekir çünkü verimli değildir (orijinal görüntü varsayın 2n * 2n)

1 0 1 0 
0 0 0 0 
1 0 1 0 
0 0 0 0 

Not: Matriste birden çok işlem yapıyorum. Herhangi bir yardım takdir edilir. Sen orijinal matris yarım boyutu ile bir matris üzerinde yararsız satır ve sütun, ve iş kaldırabilir

cevap

6

önceden

sayesinde.

En yakın interpolasyonlu, resize fonksiyonu ile kolayca yapabilirsiniz

:

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace cv; 
using namespace std; 

int main(int argc, char **argv) 
{ 
    Mat1b mat = (Mat1b(4,4) << 0, 1, 2, 3, 
           4, 5, 6, 7, 
           8, 9, 10, 11, 
           12, 13, 14, 15); 

    Mat1b res; 
    resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST); 

    cout << "Mat:" << endl << mat << endl << endl; 
    cout << "Res:" << endl << res << endl; 

    return 0; 
} 

Sonra res değerler endeksleri de yalnızca değerleri ihtiyacınız olan

:

Mat: 
[0, 1, 2, 3; 
4, 5, 6, 7; 
8, 9, 10, 11; 
12, 13, 14, 15] 

Res: 
[0, 2; 
8, 10] 

Değerleri orijinal konumuna geri yüklemek için, Kronecker ürününü (OpenCV'de mevcut değildir, ancak easily implemented olabilir) uygun bir şekilde kullanabilirsiniz. desen Bu üretecek:

Mat: 
[0, 1, 2, 3; 
4, 5, 6, 7; 
8, 9, 10, 11; 
12, 13, 14, 15] 

Res: 
[0, 2; 
8, 10] 

Res Modified: 
[1, 3; 
9, 11] 

Restored: 
[1, 0, 3, 0; 
0, 0, 0, 0; 
9, 0, 11, 0; 
0, 0, 0, 0] 

Kodu:

#include <opencv2/opencv.hpp> 
#include <algorithm> 
#include <iostream> 
using namespace cv; 
using namespace std; 

Mat kron(const Mat A, const Mat B) 
{ 
    CV_Assert(A.channels() == 1 && B.channels() == 1); 

    Mat1d Ad, Bd; 
    A.convertTo(Ad, CV_64F); 
    B.convertTo(Bd, CV_64F); 

    Mat1d Kd(Ad.rows * Bd.rows, Ad.cols * Bd.cols, 0.0); 

    for (int ra = 0; ra < Ad.rows; ++ra) 
    { 
     for (int ca = 0; ca < Ad.cols; ++ca) 
     { 
      Kd(Range(ra*Bd.rows, (ra + 1)*Bd.rows), Range(ca*Bd.cols, (ca + 1)*Bd.cols)) = Bd.mul(Ad(ra, ca)); 
     } 
    } 
    Mat K; 
    Kd.convertTo(K, A.type()); 
    return K; 

} 


int main(int argc, char **argv) 
{ 
    Mat1b mat = (Mat1b(4, 4) << 0, 1, 2, 3, 
     4, 5, 6, 7, 
     8, 9, 10, 11, 
     12, 13, 14, 15); 

    Mat1b res; 
    resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST); 

    cout << "Mat:" << endl << mat << endl << endl; 
    cout << "Res:" << endl << res << endl << endl; 

    // Work on Res 
    res += 1; 

    cout << "Res Modified:" << endl << res << endl << endl; 

    // Define the pattern 
    Mat1b pattern = (Mat1b(2,2) << 1, 0, 
            0, 0); 

    // Apply Kronecker product 
    Mat1b restored = kron(res, pattern); 

    cout << "Restored:" << endl << restored << endl << endl; 

    return 0; 
} 
+0

bu ilk etapta OP'ın niyeti olsaydı beni merak ediyor? Bir parça tekerlek icat hiç kimseyi incitmez :) –

+0

Çok teşekkürler. Bu çok iyi bir çözüm. Eğer bir şekilde 4 * 4 matrisini elde edebilecek olsaydım, sadece indeksler [0,2; 8,10] sıfırdı, geri kalanı ise sıfırdır. Örneğin. Diğer işlemlerden sonra 'res = [1, 9; 5, 7]; 'Ben bu değerleri 4 * 4 matrisinde pozisyonlarına almak istiyorum ve geri kalanlar sıfırdır. En son matris, [1,0,9,0; 0,0,0,0; 5,0,7,0; 0,0,0,0] '. Bu kesinlikle hızlandıracak ama ben biraz açgözlü değilim :) – smttsp

+0

@sm Bunu anlamıyorum, detaylandırır mısınız lütfen? – Miki

İlgili konular