enum { CV8U=0, CV8S=1, CV16U=2, CV16S=3, CV32S=4, CV32F=5, CV_64F=6 }
取像素点的各个通道值 单通道: img.at<uchar>(i,j)三通道: img.at<Vec3b>(j,i)[0] img.at<Vec3b>(j,i)[1] img.at<Vec3b>(j,i)[2] 图像按颜色分类: 二值图:图像颜色只有黑白两种构成 无符号位的单通道灰度图:图像颜色由白到黑色之间颜色构成 无符号位的单通道彩色图:图像颜色由bgr三原色构成的各种颜色构成 三通道(四通道带有透明度) 1. 载入,显示,保存图像 imread(“图像名”,int flag); flag: >0:返回3通道的彩色图 特例:如果原图为黑白图,flag=2时,返回的还是黑白图非彩色图 =0:返回灰度图 <0:返回原图(带alpha通道) imwrite(“文件名”,要保存图像的Mat对象);imshow(“图像名”,Mat对象); 2. 使用迭代器遍历图像 Mat_<Vec3b>::interator it = image.begin<Vec3b>();Mat_<Vec3b>:interator itenfd = image.end<Vec3b>();for(;it!=itend;++it){ (*it)[0] = (*it)[0]/div*div+div/2; (*it)[1] = (*it)[1]/div*div+dov/2; (*it)[2] = (it)[2]/div*div+div/23;} 3.遍历图像和邻域操作应用实例: 图像的锐化
锐化公式: sharpened_pixel = 5*current-left-right-up-down; //该位置的像素值的5倍减去与其相邻的点的像素值,必须是上下左右都有像素
核矩阵:
图像滤波器:
4. 颜色缩减 例如:CV_8UC3 — 三通道的八位无符号整数表示像素值,像素值一共有256256256种可能倘若一幅图包含这些像素值,存储起来是很浪费空间的
因此需要缩减颜色种类的数量,也就是像素值的所有可能取值的情况和
具体的颜色缩减的策略: 5. 图像掩模(或掩模) 为8位单通道图像(灰度图或二值图)掩码某个位置为0,则在此位置上操作不起作用, 掩码某个位置不为0,则在此位置上操作起作用可以用来提取不规则ROI示例代码 #include "opencv2/opencv.hpp"using namespace cv;/*掩码的使用 掩码: 8位单通道图像从一幅图中选取感兴趣区域,使用掩码(形状是根据掩码的非零像素形状决定的) 可以先创建一个像素值全为零的 Mat对象,然后在图像中画长方形,圆形,多边形等 (设置该区域的像素值为255) 作为掩码(即要操作的区域) 如果 按照掩码操作后 得到图像的边缘有问题 ,肯定是边缘部分的黑色不够完善,则此时需要二值化操作,将边缘部分一律变黑 把多通道的图像怎么读成单通道的图像的原理*/void main() { Mat img = imread("a.png");//背景 Mat girlImg = imread("girl.jpg");//前景女孩 Mat mask = imread("mask.jpg",0);//掩码 Mat mask1 = Mat::zeros(girlImg.size(), CV_8UC1); Mat logo = imread("opencv.jpg"); Mat mask2 = imread("opencv.jpg", 0); //图像逻辑相加 中 使用 掩码 ,像素值为0的区域不用考虑 Mat img1 = imread("3.jpg"); Mat img2 = imread("4.jpg"); Mat mask3 = Mat::ones(img1.size(), CV_8UC1); circle(mask3, Point(mask3.cols / 2, mask3.rows / 2), 100, Scalar(0), -1, 8); Mat dst1 = img2.clone(); add(img1, img2, dst1,mask3); namedWindow("dst1", CV_WINDOW_NORMAL); imshow("dst1", dst1); circle(mask1, Point(mask.rows / 2, mask.cols / 2), 100,Scalar(255), -1, 8); //imwrite("mask1,jpg", mask1); //对mask2像素值取反,255变为0,变成黑色的掩码区域即不用考虑了 bitwise_not(mask2, mask2); namedWindow("mask2",CV_WINDOW_NORMAL); imshow("mask2", mask2); //二值化取反后的mask2, 为了边缘处理 threshold(mask2, mask2, 100, 255, THRESH_BINARY); namedWindow("二值化后的mask2",CV_WINDOW_NORMAL); imshow("二值化后的mask2",mask2); //在背景图片中选取 两块感兴趣区域 Mat imgROI = img(内向的高跟鞋t(106, 128, girlImg.cols, girlImg.rows)); Mat imgROI1 = img(内向的高跟鞋t(0, 0, logo.cols, logo.rows)); //把两张前景图片按照掩码的方式 复制到 感兴趣区域中 girlImg.copyTo(imgROI,mask1); logo.copyTo(imgROI1,mask2);//复制非黑色区域的部分 imshow("dsr", img); imwrite("result.png", img); waitKey(0);} 运行结果6. ROI(感兴趣区域) — regin of interest 可以只对感兴趣区域进行图像的处理,例如图像的覆盖,区域图像颜色改变在某一幅图中选出感兴趣区域 Mat img;Mat imgROI;imgOROI = img(内向的高跟鞋(左上角横坐标,左上角纵坐标,宽度,高度);或者 imgROI = img(Range(起始行数,终止行数).Range(起始列数,终止列数));imgROI = img.rowRange(start,end);//创建包含原始图像的特定行imgROI = img.colRange(start,end);//创建包含原始图像的特定列row(i) 是 rowRange(start,end)的特例,返回的是Mat对象col(j) 是 colRange(start,end)的特例,返回的是Mat对象 在原图中选出感兴趣区域,并用logo这张图进行添加 1.像素值相加处理Mat imgROI;//声明感兴趣区域Mat img;//原图像imgROI = img(内向的高跟鞋(0,0,logo.cols,logo.rows));//在原图像抠出感兴趣区域(矩形)addWeighted(imgROI,1.0,logo,0.3,0.,imgROI);//在感兴趣区域与logo图像直接相加(可能出现像素饱和)2.像素值的替换imgROI = img(内向的高跟鞋(23,34,logo.cols,logo.rows));//声明感兴趣区域Mat mask = immread("logo.bmp",0);//加载掩模.必须是灰度图logo.copyTo(imgROI,mask);//通过掩模拷贝ROI
7. 图像的运算 算术运算 + dst = img1 + img2; add() add(img1,img2,dst); addWeighted() addWeighted(img1,0.5,img2,0.5,0,dst);//0.5是各自图像像素值的比重 – dst = img1 -img2; substract() substract(img1, img1,dst); 像素差小于零按零计算 absdiff() absdiff(img1,img2,dst); 像素差按绝对值计算 * dst = A * img1; / dst = img1 /A; 逻辑运算 bitwise_and(srcImg1,srcImg2,outImg,mask);bitwise_or(srcImg1,srcImg2,outImg,mask);bitwise_not(srcImg,outImg,mask);bitwise_xor(srcImg1,srcImg2,outImg,mask);//异或运算,各自图像中独有的部分的并集
转载于:https://www.cnblogs.com/luohongyi/p/6754400.html