//图像操作--转换成单通道图像,并反差;三通道图像反差
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src,dst1;
src = imread("F:/xxx/xxx.jpg");
if (src.empty())
{
printf("could not load image...");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
/*
//转为单通道
cvtColor(src, dst1, CV_BGR2GRAY);
namedWindow("output image", CV_WINDOW_AUTOSIZE);
imshow("output image", dst1);
int high = dst1.rows;
int width = dst1.cols;
for (int row = 0; row < high; row++)
{
for (int col = 0; col < width; col++)
{
int imgvalue = dst1.at<uchar>(row, col);
dst1.at<uchar>(row, col) = 255 - imgvalue;//做一个像素值反差
}
}
namedWindow("invert image", CV_WINDOW_AUTOSIZE);
imshow("invert image", dst1);*/
Mat dst2;
dst2.create(src.size(), src.type());
int high = src.rows;
int width = src.cols;
int nc = src.channels();
/*for (int row = 0; row < high; row++)
{
for (int col = 0; col < width; col++)
{
if (1 == nc)//单通道像素值反差
{
int imgvalue = dst1.at<uchar>(row, col);
dst1.at<uchar>(row, col) = 255 - imgvalue;//做一个像素值反差
}
else if (3 == nc)//三通道像素值反差
{
int b = src.at<Vec3b>(row, col)[0];
int g = src.at<Vec3b>(row, col)[1];
int r = src.at<Vec3b>(row, col)[2];
dst2.at<Vec3b>(row, col)[0] = 255 - b;
dst2.at<Vec3b>(row, col)[1] = 255 - g;
dst2.at<Vec3b>(row, col)[2] = 255 - r;
}
}
}
namedWindow("invert1 image", CV_WINDOW_AUTOSIZE);
imshow("invert1 image", dst2);*/
//用API实现三通道像素值反差
bitwise_not(src, dst2);
namedWindow("invert2 image", CV_WINDOW_AUTOSIZE);
imshow("invert2 image", dst2);
waitKey(0);
return 0;
//读入原始图像
Mat src,dst1;
src = imread("F:/opencvtestpicture/redhairgirl.jpg");
if (src.empty())
{
printf("could not load image...");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
运行结果:
//转为单通道
cvtColor(src, dst1, CV_BGR2GRAY);
namedWindow("output image", CV_WINDOW_AUTOSIZE);
imshow("output image", dst1);
运行结果:
//对像素值进行反差
int high = dst1.rows;
int width = dst1.cols;
for (int row = 0; row < high; row++)
{
for (int col = 0; col < width; col++)
{
int imgvalue = dst1.at<uchar>(row, col);
dst1.at<uchar>(row, col) = 255 - imgvalue;//做一个像素值反差
}
}
printf("%d\n", dst1.at<uchar>(2, 2));//输出反差后第二行第二列位置点的像素值。
namedWindow("invert image", CV_WINDOW_AUTOSIZE);
imshow("invert image", dst1);
运行结果:
使用了两个for循环,外边的for控制行的遍历,内部的for控制列的遍历。最为主要的是这句:dst1.at(row, col),获取该点的像素值。进行的是赋值操作,注意dst1这个名称没有改变,如果上面没有对灰度图像进行输出,则dst1直接是反差图像。在这里需要记住的是at(2, 2)是用来获取某点像素值。
//三通道图像反差
Mat dst2;
dst2.create(src.size(), src.type());
int high = src.rows;
int width = src.cols;
int nc = src.channels();
/*for (int row = 0; row < high; row++)
{
for (int col = 0; col < width; col++)
{
if (1 == nc)//单通道像素值反差
{
int imgvalue = dst1.at<uchar>(row, col);
dst1.at<uchar>(row, col) = 255 - imgvalue;
}
else if (3 == nc)//三通道像素值反差
{
int b = src.at<Vec3b>(row, col)[0];
int g = src.at<Vec3b>(row, col)[1];
int r = src.at<Vec3b>(row, col)[2];
dst2.at<Vec3b>(row, col)[0] = 255 - b;
dst2.at<Vec3b>(row, col)[1] = 255 - g;
dst2.at<Vec3b>(row, col)[2] = 255 - r;
}
}
}
namedWindow("invert1 image", CV_WINDOW_AUTOSIZE);
imshow("invert1 image", dst2);*/
运行结果:
核心是:at(row, col)[n],相比于at(row,col)多了一个通道[n]。
//用API实现三通道像素值反差
bitwise_not(src, dst2);
namedWindow("invert2 image", CV_WINDOW_AUTOSIZE);
imshow("invert2 image", dst2);
实现结果和上面一样,区别是这里直接调用API:bitwise_not()实现(bitwise是按位的意思,后缀:-wise,表示方向,状态)。反差操作的实质是用像素范围的最大取值减去当前像素值作为该点的像素值,实现的效果是:图像中暗的区域变亮,亮的区域变暗。