灰度圖在內存中的存儲形式
3通道圖在內存中的存儲形式
1. 通過 .at<typename>(i,j) 遍歷
void colorReduce(Mat& image,int div)
{
for(int i=0;i<image.rows;i++)
{
for(int j=0;j<image.cols;j++)
{
image.at<Vec3b>(i,j)[0]=image.at<Vec3b>(i,j)[0]/div*div+div/2;
image.at<Vec3b>(i,j)[1]=image.at<Vec3b>(i,j)[1]/div*div+div/2;
image.at<Vec3b>(i,j)[2]=image.at<Vec3b>(i,j)[2]/div*div+div/2;
}
}
}
image.at<uchar>(i,j):取出灰度圖像中i行j列的點。
image.at<Vec3b>(i,j)[k]:取出彩色圖像中i行j列第k通道的顏色點,k=[0,1,2],分別代表B,G,R。
uchar,Vec3b都是圖像像素值的類型,在core裏它是通過typedef Vec<T,N>來定義的,N代表元素的個數,T代表類型。
OpenCV定義了一個Mat的模板子類爲Mat_,它重載了operator()讓我們可以更方便的取圖像上的點。
Mat m2(300, 500, CV_8UC3, Scalar(0, 0, 0));
Mat_<Vec3b> im = m2;
for (int i = 0; i < im.rows; i++) {
for (int j = 0; j < im.cols; j++) {
im(i, j)[0] = im(i, j)[0] + (uchar) (255 / 2);
im(i, j)[1] = im(i, j)[1] + (uchar) 0;
im(i, j)[2] = im(i, j)[2] + (uchar) (111 / 2);
}
}
2. 通過行指針 .ptr<uchar>(k)來遍歷
void colorReduce(const Mat& image,Mat& outImage,int div)
{
// 創建與原圖像等尺寸的圖像
outImage.create(image.size(),image.type());
int nr=image.rows;
// 將3通道轉換爲1通道
int nl=image.cols*image.channels();
for(int k=0;k<nr;k++)
{
// 每一行圖像的指針
const uchar* inData=image.ptr<uchar>(k);
uchar* outData=outImage.ptr<uchar>(k);
for(int i=0;i<nl;i++)
{
outData[i]=inData[i]/div*div+div/2;
}
}
}
3. 通過迭代器Mat_iterator來遍歷
void colorReduce(const Mat& image,Mat& outImage,int div)
{
outImage.create(image.size(),image.type());
// 獲得迭代器
MatConstIterator_<Vec3b> it_in=image.begin<Vec3b>();
MatConstIterator_<Vec3b> itend_in=image.end<Vec3b>();
MatIterator_<Vec3b> it_out=outImage.begin<Vec3b>();
MatIterator_<Vec3b> itend_out=outImage.end<Vec3b>();
while(it_in!=itend_in)
{
(*it_out)[0]=(*it_in)[0]/div*div+div/2;
(*it_out)[1]=(*it_in)[1]/div*div+div/2;
(*it_out)[2]=(*it_in)[2]/div*div+div/2;
it_in++;
it_out++;
}
}