网站设计规划的一般流程/seo优化的主要任务
1. 彩色通道分离
之前在轮渡的时候,看到安检还蛮累的,注意到他们屏幕上的图片还是蛮清楚的。
(奇怪,今天怎么都上传不了图像。)
突然就有了一个想法,如果能够根据不同的物件分离颜色的通道后再用神经网络去识别的话,想必会更加精准的。
那就涉及到色道分离啦。Opencv里有个函数能够做到将一张彩色图片的三通道分再保存到图像中。
越接近正色的区域就越白。
// opencv_day9.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"using namespace std;
using namespace cv;int main()
{Mat src = imread("1.png");imshow("原图", src);vector<Mat> channels;split(src, channels);//分离色彩通道Mat red = channels[2];Mat green = channels[1];Mat blue = channels[0];imshow("蓝色通道", blue);imshow("绿色通道", green);imshow("红色通道", red);waitKey(0);return 0;
}
2. Opencv分水岭算法——watershed自动图像分割用法
分水岭算法在边缘算法中算是比较特别的,之前的阈值,边缘检测得出的都不是连续闭合的边缘,分水岭算法是将图像分割成一块一块。它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特征。
Opencv 中 watershed函数原型:
void watershed( InputArray image, InputOutputArray markers );
第一个参数是一个彩色图像。
第二个就比较多考究了:
在执行分水岭函数watershed之前,必须对第二个参数markers进行处理,它应该包含不同区域的轮廓,每个轮廓有一个自己唯一的编号,轮廓的定位可以通过Opencv中findContours方法实现,这个是执行分水岭之前的要求。
算法会根据markers传入的轮廓作为种子(也就是所谓的注水点),对图像上其他的像素点根据分水岭算法规则进行判断,并对每个像素点的区域归属进行划定,直到处理完图像上所有像素点。而区域与区域之间的分界处的值被置为“-1”,以做区分。
Opencv官方例程中使用鼠标划线标记,其实就是在定义种子,只不过需要手动操作,而使用findContours可以自动标记种子点。而分水岭方法完成之后并不会直接生成分割后的图像,还需要进一步的显示处理
感觉这个分水岭函数还是有些小麻烦啊。
补充下轮廓检测的知识:https://blog.csdn.net/guduruyu/article/details/69220296
// opencv_day9.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"#include <iostream>using namespace cv;
using namespace std;Vec3b RandomColor(int value); //生成随机颜色函数int main()
{Mat image = imread("1.jpg"); //载入RGB彩色图像imshow("Source Image", image);resize(image, image, Size(image.cols / 2, image.rows / 2));//灰度化,滤波,Canny边缘检测Mat imageGray;cvtColor(image, imageGray, CV_RGB2GRAY);//灰度转换GaussianBlur(imageGray, imageGray, Size(5, 5), 2); //高斯滤波imshow("Gray Image", imageGray);Canny(imageGray, imageGray, 80, 150);//边缘检测imshow("Canny Image", imageGray);//查找轮廓vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(imageGray, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());//找轮廓Mat imageContours = Mat::zeros(image.size(), CV_8UC1); //轮廓 Mat marks(image.size(), CV_32S); //Opencv分水岭第二个矩阵参数marks = Scalar::all(0);int index = 0;int compCount = 0;for (; index >= 0; index = hierarchy[index][0], compCount++){//对marks进行标记,对不同区域的轮廓进行编号,相当于设置注水点,有多少轮廓,就有多少注水点drawContours(marks, contours, index, Scalar::all(compCount + 1), 1, 8, hierarchy);//第三个参数是第几个轮廓的意思,如果为-1则为全部轮廓drawContours(imageContours, contours, index, Scalar(255), 1, 8, hierarchy);}//我们来看一下传入的矩阵marks里是什么东西Mat marksShows;convertScaleAbs(marks, marksShows);//转换marks为8位的图像imshow("marksShow", marksShows);imshow("轮廓", imageContours);watershed(image, marks);//我们再来看一下分水岭算法之后的矩阵marks里是什么东西Mat afterWatershed;convertScaleAbs(marks, afterWatershed);imshow("After Watershed", afterWatershed);//对每一个区域进行颜色填充Mat PerspectiveImage = Mat::zeros(image.size(), CV_8UC3);for (int i = 0; i<marks.rows; i++){for (int j = 0; j<marks.cols; j++){int index = marks.at<int>(i, j);if (marks.at<int>(i, j) == -1){PerspectiveImage.at<Vec3b>(i, j) = Vec3b(255, 255, 255);}else{PerspectiveImage.at<Vec3b>(i, j) = RandomColor(index);}}}imshow("After ColorFill", PerspectiveImage);//分割并填充颜色的结果跟原始图像融合Mat wshed;addWeighted(image, 0.4, PerspectiveImage, 0.6, 0, wshed);imshow("AddWeighted Image", wshed);waitKey();
}Vec3b RandomColor(int value)//生成随机颜色函数</span>
{value = value % 255; //生成0~255的随机数RNG rng;int aa = rng.uniform(0, value);int bb = rng.uniform(0, value);int cc = rng.uniform(0, value);return Vec3b(aa, bb, cc);
}
3.3 void cv::addWeighted ()
3.3.1 函数用途
矩阵加权加法
3.3.2 函数原型
void cv::addWeighted
(
InputArray src1,
double alpha,
InputArray src2,
double beta,
double gamma,
OutputArray dst,
int dtype = -1
)
3.3.2 函数参数
src1 输入第一个矩阵
alpha 第一个矩阵元素的权重
src2 输入第二个矩阵(和第一个矩阵具有相同大小和通道数)
beta 第二个矩阵元素的权重
gamma 权重和加上一个标量
dst 输出矩阵(和输入矩阵具有相同大小和通道数)
dtype 设置输出矩阵的深度
可以实现半透明状覆盖到另一张图片的效果。