想快速入门图像处理的小伙伴们!跟着步伐我们一起闯关吧!一定会收获满满哦!
为图像处理初学者设计的 100 个问题。这里感谢@gzr2017的翻译,然后我也将随作者的脚步逐一学习实现100道算法题,大家可以一起学习哦,加油!坚持!持续更新中哦!!!
问题1-5:
- 问题一:通道交换
- 问题二:灰度化(Grayscale)
- 问题三:二值化(Thresholding)
- 问题四:大津二值化算法(Otsu’s Method)
- 问题五:HSV转换
代码实现:
- 问题一:通道交换
读取图像,然后将RGB通道替换成BGR通道。
#include<opencv2/highgui.hpp>
#include<opencv2/core.hpp>
#include<iostream>
using namespace cv;
Mat channel_swap(Mat img)
{
int height = img.rows;
int width = img.cols;
//准备一个与原图像格式尺寸相同的黑色模板
Mat out = Mat::zeros(height, width, CV_8UC3);
for (size_t y = 0; y <height; y++)
{
for (size_t x = 0; x < width; x++)
{
out.at<Vec3b>(y, x)[0] = img.at<Vec3b>(y, x)[2];//R->B
out.at<Vec3b>(y, x)[1] = img.at<Vec3b>(y, x)[1];//G->G
out.at<Vec3b>(y, x)[2] = img.at<Vec3b>(y, x)[0];//B->R
}
}
return out;
}
int main()
{
//读取图片
Mat img = imread("D:/文件/lenna.png");
Mat out = channel_swap(img);
imshow("img", img);
imshow("out", out);
waitKey(0);
destroyAllWindows();
return 0;
}
输入:
输出:
Note:
1、imread()读取图像通道的顺序为BGR
2、vector说明
< Vec3f > 浮点
< Vec3d > double
< Vec3b > 8U 类型的 RGB 彩色图像 (0-255)
- 问题二:灰度化(Grayscale)
将图像灰度化。
灰度是一种图像亮度的表示方法,通过下式计算:
Y = 0.2126\ R + 0.7152\ G + 0.0722\ B
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
Mat BGR2GRAY(Mat img)
{
int height = img.rows;
int width = img.cols;
Mat out = Mat::zeros(height, width, CV_8UC1);
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
out.at<uchar>(y, x) = 0.2126*(float)img.at<Vec3b>(y, x)[2]
+ 0.7152*(float)img.at<Vec3b>(y, x)[1]
+ 0.0722*(float)img.at<Vec3b>(y, x)[0];
}
}
return out;
}
int main(int argc, const char* argv[])
{
Mat img = imread("D:/文件/lenna.png");
Mat out = BGR2GRAY(img);
imshow("img", img);
imshow("out", out);
waitKey(0);
destroyAllWindows();
return 0;
}
输入:
输出:
- 问题三:二值化(Thresholding)
将图像进行二值化。
二值化是将图像使用黑和白两种颜色表示的方法。我们将阈值设置为128来进行二值化。
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
//BGR->GRAY
Mat BGR2GRAY(Mat img)
{
int height = img.rows;
int width = img.cols;
Mat out = Mat::zeros(height, width, CV_8UC1);
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
out.at<uchar>(y, x) = 0.2126*(float)img.at<Vec3b>(y, x)[2]
+ 0.7152*(float)img.at<Vec3b>(y, x)[1]
+ 0.0722*(float)img.at<Vec3b>(y, x)[0];
}
}
return out;
}
//GRAY->BINARIZE
Mat Binarize(Mat img,int th)//th用来设置二值化阈值
{
int height = img.rows;
int width = img.cols;
Mat out = Mat::zeros(height, width, CV_8UC1);
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
if (img.at<uchar>(y, x) < th)
out.at<uchar>(y, x) = 0;
else
out.at<uchar>(y, x) = 255;
}
}
return out;
}
int main(int argc, const char* argv[])
{
Mat img = imread("D:/文件/lenna.png");
Mat out = Binarize(BGR2GRAY(img), 128);
imshow("img", img);
imshow("out", out);
waitKey(0);
destroyAllWindows();
return 0;
}
输入:
输出:
- 问题四:大津二值化算法(Otsu’s Method)
用大津算法二值化图像。
推荐这篇博客,写的比较清晰。
https://blog.csdn.net/u012198575/article/details/81128799
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
//BGR->GRAY
Mat BGR2GRAY(Mat img)
{
int height = img.rows;
int width = img.cols;
Mat out = Mat::zeros(height, width, CV_8UC1);
for (size_t y = 0; y < height; y++