1月11日-2月8日
#include
#include
using namespace cv;
using namespace std;
int main(int artc, char** argv) {
Mat src = imread("D:/images/test.png");
if (src.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
// 直接读取图像像素
int height = src.rows;
int width = src.cols;
int ch = src.channels();
for (int c = 0; c < ch; c++) {
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (ch == 3) {
Vec3b bgr = src.at<Vec3b>(row, col);
bgr[0] = 255 - bgr[0];
bgr[1] = 255 - bgr[1];
bgr[2] = 255 - bgr[2];
src.at<Vec3b>(row, col) = bgr;
}
else if (ch == 1) {
int gray = src.at<uchar>(row, col);
src.at<uchar>(row, col) = 255 - gray;
}
}
}
}
imshow("output", src);
// 指针读取
Mat result = Mat::zeros(src.size(), src.type());
int blue = 0, green = 0, red = 0;
int gray;
for (int c = 0; c < ch; c++) {
for (int row = 0; row < height; row++) {
uchar* curr_row = src.ptr<uchar>(row);
uchar* result_row = result.ptr<uchar>(row);
for (int col = 0; col < width; col++) {
if (ch == 3) {
blue = *curr_row++;
green = *curr_row++;
red = *curr_row++;
*result_row++ = blue;
*result_row++ = green;
*result_row++ = red;
}
else if (ch == 1) {
gray = *curr_row++;
*result_row++ = gray;
}
}
}
}
imshow("result", result);
waitKey(0);
return 0;
}
// 直接读取图像像素
int height = src.rows;
int width = src.cols;
int ch = src.channels(); // 读取通道数
for (int c = 0; c < ch; c++) {
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (ch == 3) {
Vec3b bgr = src.at<Vec3b>(row, col); // 读取每一个像素的BGR值
bgr[0] = 255 - bgr[0]; // 相当于取反值
bgr[1] = 255 - bgr[1]; // 此操作即为取反色
bgr[2] = 255 - bgr[2]; // BGR三个通道
src.at<Vec3b>(row, col) = bgr;
}
else if (ch == 1) {
int gray = src.at<uchar>(row, col);
src.at<uchar>(row, col) = 255 - gray;
}
}
}
}
imshow("output", src);
uchar及Vec3b都是图像像素值的类型
本方法缺点就是由于通过数组一个个读取,读取速度较慢。
// 指针读取
Mat result = Mat::zeros(src.size(), src.type()); // 创建空白图像
int blue = 0, green = 0, red = 0;
int gray;
for (int c = 0; c < ch; c++) {
for (int row = 0; row < height; row++) {
uchar* curr_row = src.ptr<uchar>(row); //每行原像素头地址
uchar* result_row = result.ptr<uchar>(row);
for (int col = 0; col < width; col++) {
if (ch == 3) {
blue = *curr_row++;
green = *curr_row++;
red = *curr_row++;
*result_row++ = blue;
*result_row++ = green;
*result_row++ = red;
}
else if (ch == 1) {
gray = *curr_row++;
*result_row++ = gray;
}
}
}
}
imshow("result", result);
#include
#include
using namespace cv;
using namespace std;
int main(int artc, char** argv) {
Mat src1 = imread("D:/vcprojects/images/LinuxLogo.jpg");
Mat src2 = imread("D:/vcprojects/images/WindowsLogo.jpg");
if (src1.empty() || src2.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input1", src1);
imshow("input2", src2);
int height = src1.rows;
int width = src1.cols;
int b1 = 0, g1 = 0, r1 = 0;
int b2 = 0, g2 = 0, r2 = 0;
int b = 0, g = 0, r = 0;
Mat result = Mat::zeros(src1.size(), src1.type());
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
b1 = src1.at<Vec3b>(row, col)[0];
g1 = src1.at<Vec3b>(row, col)[1];
r1 = src1.at<Vec3b>(row, col)[2];
b2 = src2.at<Vec3b>(row, col)[0];
g2 = src2.at<Vec3b>(row, col)[1];
r2 = src2.at<Vec3b>(row, col)[2];
result.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b1 + b2);
result.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g1 + g2);
result.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r1 + r2);
}
}
imshow("output", result);
Mat add_result = Mat::zeros(src1.size(), src1.type()); // 加法
add(src1, src2, add_result);
imshow("add_result", add_result);
Mat sub_result = Mat::zeros(src1.size(), src1.type()); // 减法
subtract(src1, src2, sub_result);
imshow("sub_result", sub_result);
Mat mul_result = Mat::zeros(src1.size(), src1.type()); // 乘法
multiply(src1, src2, mul_result);
imshow("mul_result", mul_result);
Mat div_result = Mat::zeros(src1.size(), src1.type()); // 除法
divide(src1, src2, div_result);
imshow("div_result", div_result);
waitKey(0);
return 0;
}
关于saturate_cast函数
在图像处理方面,无论是加是减,乘除,都会超出一个像素灰度值的范围(0~255),saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。
#include
#include
using namespace cv;
using namespace std;
void customColorMap(Mat& image);
int main(int argc, const char* argv[])
{
Mat src = imread("D:/vcprojects/images/cos.jpg");
if (src.empty())
{
printf("could not load image...\n");
return -1;
}
Mat gray, dst;
// 使用LUT
applyColorMap(src, dst, COLORMAP_SUMMER);
// 显示结果
imshow("colorMap", dst);
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("gray", gray);
customColorMap(gray);
waitKey(0);
return 0;
}
void customColorMap(Mat& image) {
int lut[256];
for (int i = 0; i < 256; i++) {
if (i < 127)
lut[i] = 0;
else
lut[i] = 255;
}
// 对比度
int h = image.rows;
int w = image.cols;
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
int pv = image.at<uchar>(row, col);
image.at<uchar>(row, col) = lut[pv];
}
}
imshow("lut demo", image);
}
applyColorMap(src,dst,COLORMAP)
-src 输入图像
-dst 输出图像
-COLORMAP LUT
2.1.1 指针遍历时的取反
本次通过学习像素的读取方法,进而学习了像素的算术操作及LUT和套用LUT的使用方法。