2015-10-05 54 views
3

我有RGB图像,例如,尺寸2×2的如下:复制OpenCV中的像素值

[ 0, 14, 255, 75, 156, 255; 
    45, 255, 234, 236, 141, 255] 

我想复制每个像素(所有RGB通道的)2×2次,并获得看起来像的图像:

[ 0, 14, 255, 0, 14, 255, 75, 156, 255, 75, 156, 255; 
    0, 14, 255, 0, 14, 255, 75, 156, 255, 75, 156, 255; 
    45, 255, 234, 45, 255, 234, 236, 141, 255, 236, 141, 255; 
    45, 255, 234, 45, 255, 234, 236, 141, 255, 236, 141, 255 ] 

在Matlab中或Python,我会只需使用kron函数即可完成此操作,但我无法知道如何在OpenCV C++中轻松完成此操作。请注意,这是一个微不足道的例子,我实际上想要通过16x16来复制每个像素,并且在更大的图像上进行,而不是当然是2x2。

+0

我想'CV :: resize'与插补'INTER_NEAREST'会做的伎俩。发现一个[类似的问题](http://stackoverflow.com/questions/19342543/enlarge-image-pixels-with-opencv),确认调整大小的想法。虽然,我还没有尝试/使用过这种插值。 – wendelbsilva

+0

你可以请张贴你将如何做到这一点在Matlab? – Miki

+1

Hi @Miki,你是什么意思的Matlab?我虽然你的问题是如何使用OpenCV和C++做到这一点。无论如何,我只是尝试在这里,它的工作原理。我使用了命令'cv :: resize(m,放大,cv :: Size(m.rows * 20,m.cols * 20),20,20,cv :: INTER_NEAREST);'调整20x的大小(所以我可以查看并验证结果)。 – wendelbsilva

回答

6

您可以使用resize与近邻插值INTER_NEAREST

代码:

Mat mInput(2, 2, CV_8UC3),mOutput(4, 4, CV_8UC3); 

mInput.at<Vec3b>(0,0)= Vec3b(0,14,255); 
mInput.at<Vec3b>(0,1)= Vec3b(75,156,255); 
mInput.at<Vec3b>(1,0)= Vec3b(45,255,234); 
mInput.at<Vec3b>(1,1)= Vec3b(236,141,255); 

cout<<mInput<<"\n"; 

resize(mInput,mOutput,Size(4,4),0,0,INTER_NEAREST); 

cout<<mOutput<<"\n";;  

输出

[ 0, 14, 255, 75, 156, 255; 
    45, 255, 234, 236, 141, 255] 
[ 0, 14, 255, 0, 14, 255, 75, 156, 255, 75, 156, 255; 
    0, 14, 255, 0, 14, 255, 75, 156, 255, 75, 156, 255; 
    45, 255, 234, 45, 255, 234, 236, 141, 255, 236, 141, 255; 
    45, 255, 234, 45, 255, 234, 236, 141, 255, 236, 141, 255] 
Press any key to continue . . . 

感谢@wendelbsilva在评论指出这一点。

+0

我测试了更大的图像和更大的尺寸。只要您在'resize'中提供正确的大小,此方法就可以正常工作。你总是学到新的东西:D好电话 – Miki

+0

好极了!我不知道“调整大小”有这样的选择。 – chronosynclastic

0

你可以将kron函数包装起来,像在Matlab和Python中一样。请注意,Kronecker产品是在单通道矩阵上定义的,因此您需要拆分平面BGR矩阵,应用kron,然后合并回去。

这下面的代码即可产生精确的输出:

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

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() 
{ 
    Mat3d A(2,2); 
    A(0, 0) = Vec3d(0, 14, 255); 
    A(0, 1) = Vec3d(75, 156, 255); 
    A(1, 0) = Vec3d(45, 255, 234); 
    A(1, 1) = Vec3d(236, 141, 255); 

    cout << "A:" << endl; 
    cout << A << endl; 

    Mat1d B = Mat1d::ones(2,2); 

    cout << "B:" << endl; 
    cout << B << endl; 

    vector<Mat> planes; 
    split(A, planes); 

    for (int i = 0; i < 3; ++i) 
    { 
     planes[i] = kron(planes[i], B); 
    } 

    Mat K; 
    merge(planes, K); 

    cout << "K:" << endl; 
    cout << K << endl; 


    return 0; 
}