# 【图像处理100问】图像处理之各种像素操作效果（上）

【资源分享1】日本同行整理的视觉处理100问

```// 【1】通道转换
cv::Mat channel_swap(cv::Mat img) {
// get height and width
int width = img.cols;
int height = img.rows;

// prepare output
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);

// each y, x
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// R -> B
out.at<cv::Vec3b>(y, x)[0] = img.at<cv::Vec3b>(y, x)[2];
// B -> R
out.at<cv::Vec3b>(y, x)[2] = img.at<cv::Vec3b>(y, x)[0];
// G -> G
out.at<cv::Vec3b>(y, x)[1] = img.at<cv::Vec3b>(y, x)[1];
}
}
return out;
}```

RGB转灰度图就是根据上图公式，同样可以根据像素操作来实现：

```//【2】BGR -> Gray
cv::Mat BGR2GRAY(cv::Mat img) {
// get height and width
int width = img.cols;
int height = img.rows;

// prepare output
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC1);

// each y, x
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// BGR -> Gray
out.at<uchar>(y, x) = 0.2126 * (float)img.at<cv::Vec3b>(y, x)[2] \
+ 0.7152 * (float)img.at<cv::Vec3b>(y, x)[1] \
+ 0.0722 * (float)img.at<cv::Vec3b>(y, x)[0];
}
}
return out;
}```

```// Gray -> Binary
cv::Mat Binarize(cv::Mat gray, int th){
int width = gray.cols;
int height = gray.rows;

// prepare output
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC1);

// each y, x
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
// Binarize
if (gray.at<uchar>(y, x) > th){
out.at<uchar>(y, x) = 255;
} else {
out.at<uchar>(y, x) = 0;
}
}
}
return out;
}```

```int main()
{
Mat srcImage, grayImage,dstImage;

imshow("原图BGR", srcImage);
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);//转灰度
threshold(grayImage, dstImage, 125, 255, THRESH_BINARY);

imshow("threshold函数阈值化", dstImage);

Mat out = Binarize(grayImage,125);
imshow("自定义函数阈值化", out);//自定义函数

waitKey();
return 0;
}```

```// Gray -> Binary 输入图像为灰度图
cv::Mat Binarize_Otsu(cv::Mat gray){
int width = gray.cols;
int height = gray.rows;

// determine threshold
double w0 = 0, w1 = 0;  //被阈值 t分开的两个类中的像素数占总像素数的比率（满足相加等于1 ）
double m0 = 0, m1 = 0; //是这两个类的像素值的平均值
double max_sb = 0, sb = 0;
int th = 0;
int val;

// 遍历阈值t的可能值寻求最大值
for (int t = 0; t < 255; t++){
w0 = 0;
w1 = 0;
m0 = 0;
m1 = 0;
for (int y = 0; y < height; y++){  //遍历图像像素点
for (int x = 0; x < width; x++){
val = (int)(gray.at<uchar>(y, x)); //获取该点的灰度值

if (val < t){
w0++;
m0 += val;
} else {
w1++;
m1 += val;
}
}
}

m0 /= w0;//计算大于，小于阈值t的两类像素的像素值的平均值m0 ，m1
m1 /= w1;
w0 /= (height * width);//计算大于，小于阈值t的两类像素的个数占总个数的比例w0,w1
w1 /= (height * width);
sb = w0 * w1 * pow((m0 - m1), 2); //计算sb的平方

if(sb > max_sb){ //更新最大值
max_sb = sb;
th = t;
}
}

std::cout << "threshold:" << th << std::endl;//打印阈值

//获取阈值后，对图像进行阈值化
// prepare output
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC1);

// each y, x
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
// Binarize
if (gray.at<uchar>(y, x) > th){
out.at<uchar>(y, x) = 255;
} else {
out.at<uchar>(y, x) = 0;
}

}
}

return out;
}```

0 条评论

• ### 给彦女王生成一副蒙太奇画像

大家好呀，前两天烈阳天道1上映了，不知道大家看没看呢，里面还有一小段彦穿越虫洞与猴哥相遇的画面，彦女王啊啊啊~~

• ### 【资源分享1】日本同行整理的视觉处理100问

图像处理100问，这个项目切切实实的包含了100个各种直击你薄弱底子的问题，看完可以帮你完善很多的知识漏洞和误区。

• ### 【opencv】带你再学一遍直方图

直方图到底可以干什么呢？我觉得最明显的作用就是有利于你对这个图像进行分析了，直方图就像我们常用的统计图，只不过直方图统计的是图片的一些特征，例如像素值（这是最常...

• ### Expedition （POJ 2431）

题意：你需要驾驶一辆卡车行驶L单位长度。最开始的时候，卡车上有P单位的油。卡车每开1单位距离需要消耗1单位的汽油。如果在途中车上汽油耗尽，卡车就无法继续前行，因...

• ### LeetCode <dfs>108&109. Array & List to Binary Search Tree

Given an array where elements are sorted in ascending order, convert it to a hei...

• ### LeetCode 994. 腐烂的橘子(多源bfs)

这道题刚开始看错题了，看到了图片就以为是就是从(0, 0)那个点开始，而且只有一个，然后敲完交了就wa了，然后才发现可能刚开始坏橘子有多个，而且还...

• ### 【2020HBU天梯赛训练】7-50 部落

在一个社区里，每个人都有自己的小圈子，还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里，于是要请你统计一下，在一个给定社区中，到底有多少个互不...

• ### Tip | 数据类型占位 & 降采样 & 像素读取 & Bitmap & Color源码

下面修改通道的时候使用的是位运算， 其实对比Color源码我们知道这跟调用Color的API是一样的：

• ### 简易却高效的hashmap实现

我们每天都在使用HashMap,有没有想过,在很多情景下,HashMap做的其实没有特别好,他是一个很通用的k-v数据结构,却不一定在各个小方面都适合.因此我们...

• ### Kruscal(最小生成树)算法模版

1 const int maxn=400;//最大点数 2 const int maxm=10000;//最大边数 3 int n,m;//n表示点数，m...