/*
*开发环境:Win7,32位系统,VS2012,Win32 Console Application程序
*OpenCv版本:2.4.9
*程序功能:生成椒盐噪声,多种方式去噪
*日期:2014/12/2
*原创:是
*作者:EbowTang
*Email:tangyibiao520@163.com
*/
// ConsoleAppOpenCvMedian.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <opencv2/core/core.hpp>//cv::Mat是一个n维矩阵类
#include <opencv2/highgui/highgui.hpp>//提供输入输出接口
#include <opencv2/imgproc/imgproc.hpp>//图像处理
#include <time.h>
#include "iostream"
using namespace cv;
using namespace std;
void ColorSalt(Mat& image, int n)//本函数加入彩色盐噪声
{
srand( (unsigned)time( NULL ) );
for(int k=0; k<n; k++)//将图像中n个像素随机置零
{
int i = rand()%image.cols;
int j = rand()%image.rows;
//将图像颜色随机改变
image.at<Vec3b>(j,i)[0] = 250;
image.at<Vec3b>(j,i)[1] = 150;
image.at<Vec3b>(j,i)[2] = 250;
}
}
void ColorPepper(Mat& image, int n)//本函数加入彩色椒噪声
{
srand( (unsigned)time( NULL ) );
for(int k=0; k<n; k++)
{
int i = rand()%image.cols;
int j = rand()%image.rows;
//将图像颜色随机改变
image.at<Vec3b>(j,i)[0] = 250;
image.at<Vec3b>(j,i)[1] = 150;
image.at<Vec3b>(j,i)[2] = 50;
}
}
int main()
{
//源图像
Mat scr = imread("lena.bmp");
Mat dst;
Mat img = scr.clone();
Mat img1 = scr.clone();
cout<<scr.channels()<<" "<<scr.type()<<" "<<scr.depth();
imshow("原图像",scr);
Mat sobelx;
Sobel(scr, sobelx, CV_32F, 1, 0);
imshow("Sobel的结果",sobelx);
ColorSalt(scr, 5000); //加入白盐噪声
ColorPepper(scr, 1000); //加入黑椒噪声
imshow("带噪声的图像",scr);
medianBlur(scr,dst,3); //中值滤波,3*3模板内排序并求中值取代原像素
imshow("中值滤波结果",dst);
ColorSalt(img, 5000);
ColorPepper(img, 1000);
blur(img,dst,Size(3,3));//均值滤波,3*3模板内求取中间值取代原像素
imshow("均值滤波结果",dst);
ColorSalt(img1, 5000);
ColorPepper(img1, 1000);
GaussianBlur( img1, dst, Size( 3, 3 ), 0, 0 );//高斯滤波,
imshow("高斯滤波结果",dst);
Rect r( 0, 0, 100, 100);
//img = Scalar(50);//将图像img的像素赋值为50
Mat smallImg = img(r);//截取显示img图像中形状为r的部分图像
imshow("截图显示结果",smallImg);
waitKey(NULL);//无限等待
return EXIT_SUCCESS;
}
去噪效果如下:
为什么256级的灰度图是3个通道...?灰度图不应该是1么?
二,OpenCv+MFC实现
1,部分函数
void CMFCAppOpenCVTestDlg::OnBnClickedBtnRead()
{
// TODO: Add your control notification handler code here
m_cvImg = imread("Oct.bmp", 1);
ShowImg(GetDlgItem(IDC_STATIC_SHOW), m_cvImg);
}
void CMFCAppOpenCVTestDlg::OnBnClickedBtnMedian()
{
// TODO: Add your control notification handler code here
Mat m_cvDst = m_cvImg.clone();
medianBlur(m_cvImg,m_cvDst,3); //中值滤波,3*3模板内排序并求中值取代原像素
ShowImg(GetDlgItem(IDC_STATIC_SHOW), m_cvDst);
}
void CMFCAppOpenCVTestDlg::OnBnClickedBtnAddnoise()
{
// TODO: Add your control notification handler code here
SaltNoise(m_cvImg,5000);
ShowImg(GetDlgItem(IDC_STATIC_SHOW), m_cvImg);
}
void CMFCAppOpenCVTestDlg::SaltNoise(Mat& image, int n)
{
srand( (unsigned)time( NULL ) );
srand( (unsigned)time( NULL ) );
if (image.channels()==3)
{
for(int k=0; k<n; k++)//将图像中n个像素随机置零
{
int i = rand()%image.cols;
int j = rand()%image.rows;
//将图像颜色随机改变
image.at<Vec3b>(j,i)[0] = 250;
image.at<Vec3b>(j,i)[1] = 150;
image.at<Vec3b>(j,i)[2] = 250;
}
}
else
{
for(int k=0; k<n; k++)//将图像中n个像素随机置零
{
int i = rand()%image.cols;
int j = rand()%image.rows;
//将图像颜色随机改变
image.at<uchar>(j,i) = 250;
}
}
}
void CMFCAppOpenCVTestDlg::OnBnClickedBtnBlur()
{
// TODO: Add your control notification handler code here
Mat m_cvDst1 = m_cvImg.clone();
blur(m_cvImg,m_cvDst1,Size(3,3)); //中值滤波,3*3模板内排序并求中值取代原像素
ShowImg(GetDlgItem(IDC_STATIC_SHOW), m_cvDst1);
}
void CMFCAppOpenCVTestDlg::OnBnClickedBtnGaussianblur()
{
// TODO: Add your control notification handler code here
Mat m_cvDst2 = m_cvImg.clone();
GaussianBlur(m_cvImg,m_cvDst2,Size(3,3),0,0); //中值滤波,3*3模板内排序并求中值取代原像素
ShowImg(GetDlgItem(IDC_STATIC_SHOW), m_cvDst2);
}
2,运行效果如下: