不得不说,对于图像处理这块,我比较尴尬,经常性接触到知识的盲区,很是苦恼但却只能这样。俗话说:“学习如逆水行舟,不进则退。
首先,我来分享下这几天所学的理论知识
单通道图俗称灰度图,每个像素点只能有有一个值表示颜色,它的像素值在0到255之间,0是黑色,255是白色,中间值是一些不同等级的灰色。(也有3通道的灰度图,3通道灰度图只有一个通道有值,其他两个通道的值都是零)。
三通道图,每个像素点都有3个值表示 ,所以就是3通道。也有4通道的图。例如RGB图片即为三通道图片,RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
(摘取自百度)
在我的代码里我的三通道图的灰度化采用的是公认的公式:Gray = R * 0.299 + G * 0.587 + B * 0.114。效果不错,但是我的单通道图出了问题。不知道为何,我的单通道图采用操作像素的方法,灰度确实实现但是图片的像素点丢失,写这个博客,一是分享知识,二是寻找答案。我将非常感谢。(问题已经解决)是数据结构出错导致。代码已经更正。最后修改时间:2018年8月2日
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<vector>
using namespace cv;
using namespace std;
Mat gaycolor(Mat &inputimage, int flag)
{
if (flag == 3)
{
for (int i = 0; i < inputimage.rows; i++)
{
for (int j = 0; j < inputimage.cols; j++)
{
inputimage.at<Vec3b>(i, j)[0] = (inputimage.at<Vec3b>(i, j)[0] * 30 + inputimage.at<Vec3b>(i, j)[1]*59+ inputimage.at<Vec3b>(i, j)[2]*11)/100;
inputimage.at<Vec3b>(i, j)[1] = (inputimage.at<Vec3b>(i, j)[0] * 30 + inputimage.at<Vec3b>(i, j)[1] * 59 + inputimage.at<Vec3b>(i, j)[2] * 11) / 100;
inputimage.at<Vec3b>(i, j)[2] = (inputimage.at<Vec3b>(i, j)[0] * 30 + inputimage.at<Vec3b>(i, j)[1] * 59 + inputimage.at<Vec3b>(i, j)[2] * 11) / 100;
}
}
}
return inputimage;
}
else if (flag == 1)//单通道图像的获取方法
{
Mat outputimage(inputimage.rows, inputimage.cols, CV_8UC1);
for (int i = 0; i < inputimage.rows; i++)
{
for (int j = 0; j < inputimage.cols; j++)
{
outputimage.at<uchar>(i, j) = (inputimage.at<Vec3b>(i, j)[0] * 30 + inputimage.at<Vec3b>(i, j)[1] * 59 + inputimage.at<Vec3b>(i, j)[2] * 11) / 100;
}
}
return outputimage;
}
}
int main()
{
Mat girl = imread("G:\\素材\\he.jpg",3);
int flag;
Mat img1;
cout << "请输入通道数" << endl;
cin >> flag;
imshow("1", girl);
img1=gaycolor(girl, flag);
imshow("de", img1);
cout << img1.channels() << endl;
waitKey(0);
return 0;
}
以下是效果图: