利用Mat对象的像素数组指针来修改图片,是老司机玩的,新手的话可以采用一些安全访问的办法。
见下面的代码。
演示代码:
#include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace cv; using namespace std; int main(int argc, char** argv) { //imread 可以指定加载为灰度或者RGB图像 Mat src=imread("e:/5.png",IMREAD_GRAYSCALE); if (src.empty()) { cout << "载入图片失败..." << endl; return -1; } imshow("win1",src); //Imwrite 保存图像文件,类型由扩展名决定 imwrite("e:/5gray.bmp",src); printf("src的通道数:%d\n", src.channels()); //单通道修改像素,反相效果 //效果见图1 int row = src.rows; int col = src.cols; int channels = src.channels(); for (int i = 0; i < row; i++) { for (int k = 0; k < col; k++) { if (channels == 1) { int g=src.at<uchar>(i, k); src.at<uchar>(i, k) = 255 - g; } } } imshow("win2", src); //3通道图像反相显示,效果见图2 Mat src2 = imread("e:/5.png"); imshow("win3", src2); row = src2.rows; col = src2.cols; channels = src2.channels(); Mat src3 = src2.clone(); for (int i = 0; i < row; i++) { for (int k = 0; k < col; k++) { if (channels == 3) { int b = src3.at<Vec3b>(i, k)[0]; int g = src3.at<Vec3b>(i, k)[1]; int r = src3.at<Vec3b>(i, k)[2]; src3.at<Vec3b>(i, k)[0] = 255 - b; src3.at<Vec3b>(i, k)[1] = 255 - g; src3.at<Vec3b>(i, k)[2] = 255 - r; } } } imshow("win4", src3); //bitwise_not是对二进制数据进行“非”操作, //即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作 //效果和上面的代码是一样的。 Mat src4; src4.create(src2.size(), src2.type()); bitwise_not(src2, src4); imshow("win5", src4); //利用3通道,用min,max函数计算出新的单通道灰度图 //效果见图3 src3 = src2.clone(); Mat gray2,gray3; cvtColor(src3, gray2, COLOR_BGR2GRAY); gray3 = gray2.clone(); printf("gray2通道数:%d\n", gray2.channels()); for (int i = 0; i < row; i++) { for (int k = 0; k < col; k++) { if (channels == 3) { int b = src3.at<Vec3b>(i, k)[0]; int g = src3.at<Vec3b>(i, k)[1]; int r = src3.at<Vec3b>(i, k)[2]; gray2.at<uchar>(i, k) = max(r, max(g, b)); gray3.at<uchar>(i, k) = min(r, min(g, b)); } } } imshow("win6", gray2); imshow("win7", gray3); waitKey(0); return 0; }
(图1)
(图2)
(图3)
代码说明:
imread 可以指定加载为灰度或者RGB图像 Imwrite 保存图像文件,类型由扩展名决定
读一个GRAY像素点的像素值(CV_8UC1) Scalar intensity = img.at<uchar>(y, x); 或者 Scalar intensity = img.at<uchar>(Point(x, y)); 读一个RGB像素点的像素值 Vec3f intensity = img.at<Vec3f>(y, x); float blue = intensity.val[0]; float green = intensity.val[1]; float red = intensity.val[2];
修改像素值 :
灰度图像 img.at<uchar>(y, x) = 128; RGB三通道图像 img.at<Vec3b>(y,x)[0]=128; // blue img.at<Vec3b>(y,x)[1]=128; // green img.at<Vec3b>(y,x)[2]=128; // red 空白图像赋值 img = Scalar(0); ROI选择 Rect r(10, 10, 100, 100); Mat smallImg = img(r);
Vec3b与Vec3F:
Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。 Vec3f对应三通道的float类型数据 把CV_8UC1转换到CV32F1实现如下: src.convertTo(dst, CV_32F);
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文章代码及资料部分或全部来自贾志刚老师的视频,勇哥只是在个人理解的基础上做学习笔记,转载请附上博文链接!
本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:


