星期二, 10. 一月 2017 05:48下午
这部分主要是操作像素
Ma_的模板类
模板类可以直接申明类型,会多了一些使用方法,更加的简便,比如:
cv::Mat_<uchar> im2(image);
im2(50, 100) = 0; //访问第50行100列的值
Mat与Mat_相互转换也是很简单的。
一般情况下Mat类读取像素:
image.at<uchar>(i,j) = 255;
指针读取
除了一般的
uchar* data = image.ptr<uchar>(i);
for(int j=0;j<nc;j++)
{
data[j] = data[j]/div*div+div/2;
}
我们还可以用以下语句执行:
*data = *data/div*div + div/2 ; data++
代码演示(salt)
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
void salt(cv::Mat image, int n)
{
int i,j;
for(int k=0;k<n;k++)
{
i = std::rand()%image.rows;
j = std::rand()%image.cols;
if(image.type()==CV_8UC1)
image.at<uchar>(i,j) = 255;
else if(image.type()==CV_8UC3)
{
//cv::Vec3b表示三个8位的数值
image.at<cv::Vec3b>(i,j)[0] = 255;
image.at<cv::Vec3b>(i,j)[1] = 255;
image.at<cv::Vec3b>(i,j)[2] = 255;
}
}
}
int main()
{
cv::Mat image = cv::imread("/home/ottsion/Pictures/opencvImage/hua.jpg");
salt(image, 3000);
cv::namedWindow("image after salt");
cv::imshow("image after salt", image);
cv::waitKey(0);
}
![效果图](../../../pic/mybolg_pic/opencv/2017-01-10 17:10:51屏幕截图.png “xiaoguotu”)
代码演示减色函数
void colorReduce(cv::Mat image,int div)
{
int nl = image.rows;
int nc = image.channels()*image.cols;
for(int i=0;i<nl;i++)
{
uchar* data = image.ptr<uchar>(i);
for(int j=0;j<nc;j++)
{
data[j] = data[j]/div*div+div/2;
}
}
cv::namedWindow("image after colorReduce");
cv::imshow("image after colorReduce", image);
}
![效果图](../../../pic/mybolg_pic/opencv/2017-01-10 17:46:00屏幕截图.png “xiaoguotu”)
更有效的扫描方式:
void colorReduce6(cv::Mat image, int div=64) {
int nl= image.rows; // number of lines
int nc= image.cols * image.channels(); // total number of elements per line
if (image.isContinuous()) {
// then no padded pixels
std::cout << "Image is continuous" << std::endl;
nc= nc*nl;
nl= 1; // it is now a 1D array
}
int n= static_cast<int>(log(static_cast<double>(div))/log(2.0) + 0.5);
// mask used to round the pixel value
uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
for (int j=0; j<nl; j++) {
uchar* data= image.ptr<uchar>(j);
for (int i=0; i<nc; i++) {
// process each pixel ---------------------
*data &= mask;
*data++ += div>>1;
// end of pixel processing ----------------
} // end of line
}
}
void colorReduce7(cv::Mat image, int div=64) {
if (image.isContinuous()) {
// no padded pixels
image.reshape(1, // new number of channels
1) ; // new number of rows
}
// number of columns set accordingly
int nl= image.rows; // number of lines
int nc= image.cols*image.channels() ; // number of columns
int n= static_cast<int>(log(static_cast<double>(div))/log(2.0) + 0.5);
// mask used to round the pixel value
uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
for (int j=0; j<nl; j++) {
uchar* data= image.ptr<uchar>(j);
for (int i=0; i<nc; i++) {
// process each pixel ---------------------
*data &= mask;
*data++ += div>>1;
// end of pixel processing ----------------
} // end of line
}
}
迭代器的遍历
共有两种方式:
cv::Mat_<cv::vec3b>::iterator it = image.begin<cv::Vec3b>();
cv::MatIterator_<cv::Vec3b> it;
void colorReduceByIt(cv::Mat image, int div)
{
cv::Mat_<cv::vec3b>::iterator it = image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();
for(; it!=itend; it++)
{
(*it)[0] = (*it)[0]/div*div+div/2;
(*it)[1] = (*it)[1]/div*div+div/2;
(*it)[2] = (*it)[2]/div*div+div/2;
}
cv::namedWindow("image after colorReduceByIt");
cv::imshow("image after colorReduceByIt", image);
}
锐化效果
void sharpen(cv::Mat &image, cv::Mat &result)
{
result.create(image.size(), image.type());
int nchannels = image.channels();
for(int j=0;j<image.rows-1;j++)
{
const uchar* previous = image.ptr<const uchar>(j-1);
const uchar* current = image.ptr<const uchar>(j);
const uchar* next = image.ptr<const uchar>(j+1);
uchar *output = result.ptr<uchar>(j);
for(int i=nchannels; i<(image.cols-1)*nchannels; i++)
{
*output ++= cv::saturate_cast<uchar>(
5*current[i] - current[i-nchannels]-current[i+nchannels]-previous[i]-next[i]
);
}
}
result.row(0).setTo(cv::Scalar(0));
result.row(result.rows-1).setTo(cv::Scalar(0));
result.col(0).setTo(cv::Scalar(0));
result.col(result.cols-1).setTo(cv::Scalar(0));
cv::namedWindow("image after sharpen");
cv::imshow("image after sharpen", image);
}
![效果图](../../../pic/mybolg_pic/opencv/2017-01-10 19:29:11屏幕截图.png “xiaoguotu”)