参考了网上一些资料,其中关于直接使用Mat的data指针问题可能会有连续性这个问题,但是我在win8.1,Intel CPU上测试能够直接使用data指针
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
//
//int main()
//{
// ifstream ifs1, ifs2, ifs3, ifs4, ifs5, ifs6, ifs7, ifs8;
//
// string line1, line2, line3, line4, line5, line6, line7, line8;
//
// int cnt1 = 0, cnt2=0, cnt3=0, cnt4=0;
//
// ifs1.open("E:\\check1\\ret.txt");
// ifs2.open("E:\\check1\\fx.txt");
// ifs3.open("E:\\check1\\fy.txt");
// ifs4.open("E:\\check1\\out.txt");
//
// ifs5.open("E:\\check2\\ret.txt");
// ifs6.open("E:\\check2\\fx.txt");
// ifs7.open("E:\\check2\\fy.txt");
// ifs8.open("E:\\check2\\out.txt");
//
// while (getline(ifs1, line1) && getline(ifs5, line5)) {
// if (line1[0] == '=' && line5[0] == '=')
// cnt1++;
// if (line1 != line5) {
// cout << cnt1 << endl;
// break;
// }
// }
//
// while (getline(ifs2, line2) && getline(ifs6, line6)) {
// if (line2[0] == '=' && line6[0] == '=')
// cnt2++;
// if (line6 != line6) {
// cout << cnt2 << endl;
// break;
// }
// }
// while (getline(ifs3, line3) && getline(ifs7, line7)) {
// if (line3[0] == '=' && line7[0] == '=')
// cnt3++;
// if (line3 != line7) {
// cout << cnt3 << endl;
// break;
// }
// }
// while (getline(ifs4, line4) && getline(ifs8, line8)) {
// if (line4[0] == '=' && line8[0] == '=')
// cnt4++;
// if (line4 != line8) {
// cout << cnt4 << endl;
// break;
// }
// }
//}
//
//int main()
//{
// int i = 5;
// if (5 == i) {
// cout << i << endl;
// i = 4;
// }
// else if (4 == i) {
// cout << i << endl;
// i = 3;
// }
// else if (3 == i) {
// cout << i << endl;
// }
//}
//typedef Vec< uchar, 3 > Vec3b(so normal 8 bit)
//typedef Vec< double, 3 > Vec3d(so normal floating point)
//typedef Vec< float, 3 > Vec3f(so normal double precision)
//typedef Vec< int, 3 > Vec3i
//typedef Vec< short, 3 > Vec3s
//typedef Vec< ushort 3 > Vec3w(so normal 16 bit)
void way1()
{
Mat img = imread("E:\\lane_detection_material\\1.png");
imshow("Lena Original", img);
for (int row = 0; row < img.rows; row++)
{
for (int col = 0; col < img.cols; col++)
{
//主要是这里的代码
if (*(img.data + img.step[0] * row + img.step[1] * col + img.elemSize1() * 2) > 128)
{
//[row, col]像素的第 1 通道地址被 * 解析(blue通道)
*(img.data + img.step[0] * row + img.step[1] * col) = 255;
//[row, col]像素的第 2 通道地址被 * 解析(green通道), 关于elemSize1函数的更多描述请见 Fn1 里所列的博文链接
*(img.data + img.step[0] * row + img.step[1] * col + img.elemSize1()) = 255;
//[row, col]像素的第 3 通道地址被 * 解析(red通道)
*(img.data + img.step[0] * row + img.step[1] * col + img.elemSize1() * 2) = 255;
}
}
}
imshow("Lena Modified", img);
cvWaitKey();
}
void way2()
{
Mat img = imread("E:\\lane_detection_material\\1.png");
imshow("Lena Original", img);
for (int row = 0; row < img.rows; row++)
{
for (int col = 0; col < img.cols; col++)
{
/* 注意 Mat::at 函数是个模板函数, 需要指明参数类型, 因为这张图是具有红蓝绿三通道的图,
所以它的参数类型可以传递一个 Vec3b, 这是一个存放 3 个 uchar 数据的 Vec(向量). 这里
提供了索引重载, [2]表示的是返回第三个通道, 在这里是 Red 通道, 第一个通道(Blue)用[0]返回 */
if (img.at(row, col)[2] > 128)
img.at(row, col) = Vec3b(255, 255, 255);
}
}
imshow("Lena Modified", img);
cvWaitKey();
}
void way3()
{
Mat m(400, 400, CV_8UC3, Scalar(255, 255, 255));
// m2 是 Mat_ 类型的, 因为 m 中元素的类型是 CV_8UC3, 可以用 Vec3b 存储 3 个通道的值
// 注意 Mat_ 这种写法是错误的, 因为 CV_8UC3 只是一个宏定义
// #define CV_8UC3 CV_MAKETYPE(CV_8U, 3)
Mat_ m2 = m;
// for 循环画一个红色的实心圆
for (int y = 0; y < m.rows; y++)
{
for (int x = 0; x < m.rows; x++)
{
if (pow(double(x - 200), 2) + pow(double(y - 200), 2) - 10000.0 < 0.00000000001)
{
// Mat_ 模板类实现了对()的重载, 可以定位到一个像素
m2(x, y) = Vec3b(0, 0, 255);
}
}
}
imshow("Image", m);
cvWaitKey();
}
void way4()
{
Mat image(400, 400, CV_8UC3, Scalar(226, 46, 166));
imshow("Before", image);
int nl = image.rows; //行数
int nc = image.cols * image.channels(); // 每行的元素个数,每行的像素数*颜色通道数(RGB = 3)
int div = 2;
for (int j = 0; j < nl; j++) {
uchar* data = image.ptr(j);
for (int i = 0; i < nc; i++) {
// process each pixel ---------------------
data[i] = data[i] / div*div + div / 2;
//*data++ = *data / div*div + div / 2;
// end of pixel processing ----------------
} // end of line
}
//
//for (int row = 0; row < image.rows; row++)
//{
// if (row % 5 == 0)
// {
// // data 是 uchar* 类型的, m.ptr(row) 返回第 row 行数据的首地址
// // 需要注意的是该行数据是按顺序存放的,也就是对于一个 3 通道的 Mat, 一个像素有
// // 有 3 个通道值, [B,G,R][B,G,R][B,G,R]... 所以一行长度为:
// // sizeof(uchar) * m.cols * m.channels() 个字节
// uchar* data = image.ptr(row);
// for (int col = 0; col < image.cols; col++)
// {
// data[col * 3] = 102; //第row行的第col个像素点的第一个通道值 Blue
// data[col * 3 + 1] = 217; // Green
// data[col * 3 + 2] = 239; // Red
// }
// }
//}
imshow("After", image);
cvWaitKey();
}
void way5()
{
Mat image = imread("E:\\lane_detection_material\\1.png");
imshow("Before", image);
// get iterators
cv::Mat_::iterator it = image.begin();
cv::Mat_::iterator itend = image.end();
int div = 2;
for (; it != itend; ++it) {
// process each pixel ---------------------
(*it)[0] = (*it)[0] / div*div + div / 2;
(*it)[1] = (*it)[1] / div*div + div / 2;
(*it)[2] = (*it)[2] / div*div + div / 2;
// end of pixel processing ----------------
}
imshow("After", image);
cvWaitKey();
}
void way6()
{
Mat image = imread("E:\\lane_detection_material\\1.png");
imshow("Before", image);
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
nc = nc*nl;
nl = 1; // it is now a 1D array
}
int div = 2;
int n = static_cast(log(static_cast(div)) / log(2.0));
// 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(j);
for (int i = 0; i < nc; i++) {
// process each pixel ---------------------
*data++ = *data&mask + div / 2;
// end of pixel processing ----------------
} // end of line
}
imshow("After", image);
cvWaitKey();
}
void way7()
{
Mat img1(1000, 1000, CV_32F);
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
img1.at(i, j) = 3.2f;
}
}
Mat img2(1000, 1000, CV_32F);
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
img2.ptr(i)[j] = 3.2f;
}
}
Mat img3(1000, 1000, CV_32F);
float* pData = (float*)img3.data;
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
*(pData) = 3.2f;
pData++;
}
}
Mat img4(1000, 1000, CV_32F);
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
((float*)img3.data)[i * 1000 + j] = 3.2f;
//this way if more efficent in release verison, but slower in debug verison;
}
}
}
void print_mat(const cv::Mat &mat)
{
int rows = mat.rows;
int cols = mat.cols;
switch (mat.channels())
{
case 1:
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat.type() == CV_64F)
std::cout << mat.at(i, j) << ' ';
else if (mat.type() == CV_32F)
std::cout << mat.at(i, j) << ' ';
else if (mat.type() == CV_8U)
std::cout << (int)mat.at(i, j) << ' ';
else {
std::cout << "can't process!" << std::endl;
exit(0);
}
}
std::cout << std::endl;
}
break;
case 2:
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat.type() == CV_64FC2) {
std::cout << ((double *)mat.data)[((i * rows + j) << 1)] << ' ' << ((double *)mat.data)[((i * rows + j) << 1) + 1] << ' ';
}
else if (mat.type() == CV_32FC2) {
std::cout << ((float *)mat.data)[((i * rows + j) << 1)] << ' ' << ((float *)mat.data)[((i * rows + j) << 1) + 1] << ' ';
}
else if (mat.type() == CV_8UC2) {
std::cout << ((uchar *)mat.data)[((i * rows + j) << 1)] << ' ' << ((uchar *)mat.data)[((i * rows + j) << 1) + 1] << ' ';
}
else {
std::cout << "can't process!" << std::endl;
exit(0);
}
}
std::cout << std::endl;
}
break;
case 3:
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (mat.type() == CV_64FC3) {
std::cout << ((double *)mat.data)[((i * rows + j) << 1) + (i * rows + j)] << ' ' << ((double *)mat.data)[((i * rows + j) << 1) + (i * rows + j) + 1] << ' '
<< ((double *)mat.data)[((i * rows + j) << 1) + (i * rows + j) + 2] << ' ';
}
else if (mat.type() == CV_32FC3) {
std::cout << ((float *)mat.data)[((i * rows + j) << 1) + (i * rows + j)] << ' ' << ((float *)mat.data)[((i * rows + j) << 1) + (i * rows + j) + 1] << ' '
<< ((float *)mat.data)[((i * rows + j) << 1) + (i * rows + j) + 2] << ' ';
}
else if (mat.type() == CV_8UC3) {
int x = ((i * rows + j) << 1) + (i * rows + j);
std::cout << (int)((uchar*)mat.data)[((i * rows + j) << 1) + (i * rows + j)] << ' ' << (int)((uchar*)mat.data)[((i * rows + j) << 1) + (i * rows + j) + 1] << ' '
<< (int)((uchar*)mat.data)[((i * rows + j) << 1) + (i * rows + j) + 2] << ' ';
}
else {
std::cout << "can't process!" << std::endl;
exit(0);
}
}
std::cout << std::endl;
}
break;
default:
cout << "can't process it!" << endl;
}
}
int main()
{
double m[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
Mat M = Mat(3, 3, CV_64F, m).inv();
cout << M << endl;
Mat image = imread("D:\\logo.png");
cout << image << endl;
cout << "============================================================================" << endl;
print_mat(image);
//cout << image << endl;
//way7();
//Mat umat(3, 3, CV_8UC3);//矩阵元素为三通道浮点数
//uchar *p = (uchar*)umat.data;
//for (int i = 0; i < 9; i++) {
// uchar t = rand() & 127;
// *p++ = t;
// t = rand() & 127;
// *p++ = t;
// t = rand() & 127;
// *p++ = t;
//}
//Mat fmat(3, 3, CV_32FC3);//矩阵元素为三通道浮点数
//float *p1 = (float*)fmat.data;
//for (int i = 0; i < 9; i++) {
// float t = (rand() * 10) / 100.0;
// *p1++ = t;
// t = (rand() * 10) / 100.0;
// *p1++ = t;
// t = (rand() * 10) / 100.0;
// *p1++ = t;
//}
//Mat dmat(3, 3, CV_64FC3);//矩阵元素为三通道浮点数
//double *p2 = (double*)dmat.data;
//for (int i = 0; i < 9; i++) {
// double t = (rand() * 10) / 100.0;
// *p2++ = t;
// t = (rand() * 10) / 100.0;
// *p2++ = t;
// t = (rand() * 10) / 100.0;
// *p2++ = t;
//}
//cout << umat << endl << fmat << endl << dmat << endl;
//print_mat(umat);
//cout << "===============================================\n";
//print_mat(fmat);
//cout << "===============================================\n";
//print_mat(dmat);
//cout << "===============================================\n";
}