You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1124 lines
25 KiB

// DIP182002108Dlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "DIP182002108.h"
#include "DIP182002108Dlg.h"
#include "afxdialogex.h"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
using namespace cv;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CDIP182002108Dlg 对话框
CDIP182002108Dlg::CDIP182002108Dlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIP182002108_DIALOG, pParent)
, m_width(0)
, m_height(0)
, m_angle(0)
, m_shearRatio(0)
, m_a(0)
, m_b(0)
, m_ga(0)
, m_gb(0)
, m_pseudoMode(0)
, m_kemalSize(0)
, m_filterType(0)
, m_sharpType(0)
, m_th(0)
, m_kernalSize(0)
, m_bias(0)
, m_seedX(0)
, m_seedY(0)
, m_regionTh(0)
, m_fSeedX(0)
, m_fSeedY(0)
, m_fTh(0)
, m_morphType(0)
, m_morphSize(0)
, m_colorType(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDIP182002108Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_WIDTH, m_width);
DDX_Text(pDX, IDC_HEIGHT, m_height);
DDX_Text(pDX, IDC_ANGLE, m_angle);
DDX_Text(pDX, IDC_EDIT1, m_shearRatio);
DDX_Text(pDX, IDC_EDIT2, m_a);
DDX_Text(pDX, IDC_EDIT3, m_b);
DDX_Text(pDX, IDC_EDIT4, m_ga);
DDX_Text(pDX, IDC_EDIT5, m_gb);
DDX_Radio(pDX, IDC_RADIO1, m_pseudoMode);
DDX_Text(pDX, IDC_EDIT6, m_kemalSize);
DDX_Radio(pDX, IDC_RADIO3, m_filterType);
DDX_Radio(pDX, IDC_RADIO6, m_sharpType);
DDX_Text(pDX, IDC_EDIT7, m_th);
DDX_Text(pDX, IDC_EDIT8, m_kernalSize);
DDX_Text(pDX, IDC_EDIT9, m_bias);
DDX_Text(pDX, IDC_EDIT10, m_seedX);
DDX_Text(pDX, IDC_EDIT11, m_seedY);
DDX_Text(pDX, IDC_EDIT12, m_regionTh);
DDX_Text(pDX, IDC_EDIT13, m_fSeedX);
DDX_Text(pDX, IDC_EDIT14, m_fSeedY);
DDX_Text(pDX, IDC_EDIT15, m_fTh);
DDX_Radio(pDX, IDC_RADIO9, m_morphType);
DDX_Text(pDX, IDC_EDIT18, m_morphSize);
DDX_Radio(pDX, IDC_RADIO12, m_colorType);
}
BEGIN_MESSAGE_MAP(CDIP182002108Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CDIP182002108Dlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_OPENVIDEO, &CDIP182002108Dlg::OnBnClickedOpenvideo)
ON_BN_CLICKED(IDC_BUTTON2, &CDIP182002108Dlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_ROTATE, &CDIP182002108Dlg::OnBnClickedRotate)
ON_BN_CLICKED(IDC_HSHEAR, &CDIP182002108Dlg::OnBnClickedHshear)
ON_BN_CLICKED(IDC_VSHEAR, &CDIP182002108Dlg::OnBnClickedVshear)
ON_BN_CLICKED(IDC_LINEAR, &CDIP182002108Dlg::OnBnClickedLinear)
ON_BN_CLICKED(IDC_NONLINEAR, &CDIP182002108Dlg::OnBnClickedNonlinear)
ON_BN_CLICKED(IDC_HISTEQ, &CDIP182002108Dlg::OnBnClickedHisteq)
ON_BN_CLICKED(IDC_PSEUDO, &CDIP182002108Dlg::OnBnClickedPseudo)
ON_BN_CLICKED(IDC_SMOOTH, &CDIP182002108Dlg::OnBnClickedSmooth)
ON_BN_CLICKED(IDC_SHARP, &CDIP182002108Dlg::OnBnClickedSharp)
ON_BN_CLICKED(IDC_THRE, &CDIP182002108Dlg::OnBnClickedThre)
// ON_BN_CLICKED(IDC_BUTTON4, &CDIP182002108Dlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_ADTHRE, &CDIP182002108Dlg::OnBnClickedAdthre)
ON_BN_CLICKED(IDC_REGOINGROW, &CDIP182002108Dlg::OnBnClickedRegoingrow)
ON_BN_CLICKED(IDC_BUTTON3, &CDIP182002108Dlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_ERODE, &CDIP182002108Dlg::OnBnClickedErode)
ON_BN_CLICKED(IDC_DILATE, &CDIP182002108Dlg::OnBnClickedDilate)
ON_BN_CLICKED(IDC_MORPHOPEN, &CDIP182002108Dlg::OnBnClickedMorphopen)
ON_BN_CLICKED(IDC_MORPHCLOSE, &CDIP182002108Dlg::OnBnClickedMorphclose)
//ON_BN_CLICKED(IDC_BUTTON4, &CDIP182002108Dlg::OnBnClickedButton4)
//ON_BN_CLICKED(IDC_TOHSV, &CDIP182002108Dlg::OnBnClickedTohsv)
ON_BN_CLICKED(IDC_COLOR, &CDIP182002108Dlg::OnBnClickedColor)
ON_BN_CLICKED(IDC_BUTTON9, &CDIP182002108Dlg::OnBnClickedButton9)
END_MESSAGE_MAP()
// CDIP182002108Dlg 消息处理程序
BOOL CDIP182002108Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
cv::namedWindow("view");
HWND hWnd = (HWND)cvGetWindowHandle("view");
HWND hParent = ::GetParent(hWnd);
::SetParent(hWnd, GetDlgItem(IDC_PIC)->m_hWnd);
::ShowWindow(hParent, SW_HIDE);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CDIP182002108Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CDIP182002108Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDIP182002108Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CDIP182002108Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE, _T("*.jpg"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, _T("Image files(*.bmp,*.jpg)|*.bmp;*.jpg|All files(*.*)|*.*|"), NULL);
dlg.m_ofn.lpstrTitle = _T("打开图片");
if (dlg.DoModal() != IDOK) {
return;
}
CString filePath = dlg.GetPathName();
std::string sFileName = (CStringA)filePath;
src = imread(sFileName);
if (src.empty()) {
AfxMessageBox(_T("图像读取错误!"));
return;
}
else {
CRect rect;
GetDlgItem(IDC_PIC)->GetWindowRect(&rect);
Mat img;
resize(src, img, Size(rect.Width(), rect.Height()));
imshow("view", img);
}
}
void CDIP182002108Dlg::OnBnClickedOpenvideo()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE, _T("*.avi"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, _T("Videos files(*.avi)|*.avi|All files(*.*)|*.*|"), NULL);
dlg.m_ofn.lpstrTitle = _T("打开视频");
if (dlg.DoModal() != IDOK) {
return;
}
CString filePath = dlg.GetPathName();
std::string sFileName = (CStringA)filePath;
VideoCapture capture;
int re = capture.open(sFileName);
/*
int re = capture.open(0); //打开摄像头
int re = capture.open(“网站”); //打开网络视频
*/
if (!re) {
AfxMessageBox(_T("视频读取错误!"));
return;
}
CRect rect;
GetDlgItem(IDC_PIC)->GetWindowRect(&rect);
Mat img;
Mat frame;
while (true)
{
capture >> frame;
if (frame.empty()) {
return;
}
else {
resize(frame, img, Size(rect.Width(), rect.Height()));
imshow("view", frame);
waitKey(30);
}
}
}
void CDIP182002108Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
Mat dst;
if (src.data == NULL) {
AfxMessageBox(_T("没有图片资源!"));
}
else if ((m_width == 0) | (m_height == 0)) {
AfxMessageBox(_T("缩放尺寸不能为0!"));
}
else {
resize(src, dst, Size(m_width, m_height));
imshow("resize", dst);
}
}
void CDIP182002108Dlg::OnBnClickedRotate()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
if (src.data == NULL) {
AfxMessageBox(_T("没有图片资源!"));
}
else
{
Mat dst;
Mat rot_mat(2, 3, CV_32FC1); //旋转矩阵
//计算旋转后的画布大小
double sin_value = sin(m_angle * CV_PI / 180);
double cos_value = cos(m_angle * CV_PI / 180);
int width = src.cols;
int height = src.rows;
int rotate_width = (int)(height * fabs(sin_value) + width * fabs(cos_value));
int rotate_height = (int)(width * fabs(sin_value) + height * fabs(cos_value));
//计算旋转矩阵
Point center = Point(src.cols / 2, src.rows / 2);
double angel = m_angle;
double scale = 1; //缩放比例
rot_mat = getRotationMatrix2D(center, angel, scale);
//计算平移量
rot_mat.at<double>(0, 2) += (rotate_width - width) / 2;
rot_mat.at<double>(1, 2) += (rotate_height - height) / 2;
//仿射变换 旋转
warpAffine(src, dst, rot_mat, Size(rotate_width, rotate_height));
imshow("rotate", dst);
}
}
void CDIP182002108Dlg::OnBnClickedHshear()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
if (src.data == NULL) {
AfxMessageBox(_T("没有图片资源!"));
}
else
{
Mat dst;
Mat hShear_mat(2, 3, CV_32FC1); //水平错切矩阵
Point2f srcPoints[3]; //原图像中的三个点
Point2f dstPoints[3]; //目标图像中的三个点
srcPoints[0] = Point2f(0, 0); //左上角的点
srcPoints[1] = Point2f(0, src.rows); //左下角
srcPoints[2] = Point2f(src.cols, 0); //右上角
if (m_shearRatio >= 0) {
dstPoints[0] = Point2f(src.rows * m_shearRatio, 0); //左上角
dstPoints[1] = Point2f(0, src.rows); //左下角
dstPoints[2] = Point2f(src.cols + src.rows * m_shearRatio, 0);//右上角
}
else {
dstPoints[0] = Point2f(0, 0); //
dstPoints[1] = Point2f(src.cols*(-m_shearRatio), src.rows);
dstPoints[2] = Point2f(src.cols, 0);
}
hShear_mat = getAffineTransform(srcPoints, dstPoints); //三个点计算变换矩阵
//变换后的画布大小
int dst_width = src.cols + src.rows * fabs(m_shearRatio);
int dst_height = src.rows;
warpAffine(src, dst, hShear_mat, Size(dst_width, dst_height));
imshow("hshear", dst);
}
}
void CDIP182002108Dlg::OnBnClickedVshear()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
else
{
Mat dst;
Mat hShear_mat(2, 3, CV_32FC1); //水平错切矩阵
Point2f srcPoints[3]; //原图像中的三个点
Point2f dstPoints[3]; //目标图像中的三个点
srcPoints[0] = Point2f(0, 0); //左上角的点
srcPoints[1] = Point2f(0, src.rows); //左下角
srcPoints[2] = Point2f(src.cols, 0); //右上角
if (m_shearRatio >= 0) {
dstPoints[0] = Point2f(0, 0); //左上角
dstPoints[1] = Point2f(0, src.rows); //左下角
dstPoints[2] = Point2f(src.cols, src.cols * m_shearRatio);//右上角
}
else {
dstPoints[0] = Point2f(0, src.cols * (-m_shearRatio));
dstPoints[1] = Point2f(0, src.rows + src.cols * (-m_shearRatio));
dstPoints[2] = Point2f(src.cols, 0);
}
hShear_mat = getAffineTransform(srcPoints, dstPoints); //三个点计算变换矩阵
//变换后的画布大小
int dst_width = src.cols;
int dst_height = src.rows + src.cols * fabs(m_shearRatio);
warpAffine(src, dst, hShear_mat, Size(dst_width, dst_height));
imshow("vshear", dst);
}
}
void CDIP182002108Dlg::OnBnClickedLinear()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_a < 0 || m_b>255 || m_ga < 0 || m_gb>255)
{
AfxMessageBox(_T("灰度参数范围有误!"));
return;
}
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), g_src.type());
int tmp;
for (int i = 0; i < g_src.rows; i++)
{
for (int j = 0; j < g_src.cols; j++)
{
tmp = g_src.at<uchar>(i, j);
if (tmp < m_a)
{
dst.at<uchar>(i, j) = tmp * m_ga / m_a;
}
else if (tmp < m_b)
{
dst.at<uchar>(i, j) = (tmp - m_a) * (m_gb - m_ga) / (m_b - m_a) + m_ga;
}
else {
dst.at<uchar>(i, j) = (tmp - m_gb) * (255 - m_gb) / (255 - m_b) + m_gb;
}
}
}
imshow("线性对比度展宽", dst);
}
void CDIP182002108Dlg::OnBnClickedNonlinear()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), g_src.type());
int tmp;
for (int i = 0; i < g_src.rows; i++)
{
for (int j = 0; j < g_src.cols; j++)
{
tmp = g_src.at<uchar>(i, j);
dst.at<uchar>(i, j) = tmp * log10((float)(1 + tmp));
}
}
imshow("非线性动态范围调整", dst);
}
void CDIP182002108Dlg::OnBnClickedHisteq()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), g_src.type());
equalizeHist(g_src, dst);
imshow("直方图均衡",dst);
}
void CDIP182002108Dlg::OnBnClickedPseudo()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), CV_8UC3);
int tmp;
switch (m_pseudoMode)
{
case 0 :
for (int i = 0; i < g_src.rows; i++)
{
for (int j = 0; j < g_src.cols; j++)
{
tmp = g_src.at<uchar>(i, j);
if (tmp < 64)
{
dst.at<Vec3b>(i, j)[0] = 255;
dst.at<Vec3b>(i, j)[1] = 0;
dst.at<Vec3b>(i, j)[2] = 0; //蓝色
}
else if (tmp < 128)
{
dst.at<Vec3b>(i, j)[0] = 0;
dst.at<Vec3b>(i, j)[1] = 255;
dst.at<Vec3b>(i, j)[2] = 0; //绿色
}
else if (tmp < 192)
{
dst.at<Vec3b>(i, j)[0] = 0;
dst.at<Vec3b>(i, j)[1] = 255;
dst.at<Vec3b>(i, j)[2] = 255; //黄色
}
else
{
dst.at<Vec3b>(i, j)[0] = 0;
dst.at<Vec3b>(i, j)[1] = 0;
dst.at<Vec3b>(i, j)[2] = 255; //红色
}
}
}
break;
case 1 :
for (int i = 0; i < g_src.rows; i++)
{
for (int j = 0; j < g_src.cols; j++)
{
tmp = g_src.at<uchar>(i, j);
if (tmp < 64)
{
dst.at<Vec3b>(i, j)[0] = 255; //蓝
dst.at<Vec3b>(i, j)[1] = tmp * 256 / 64; //绿
dst.at<Vec3b>(i, j)[2] = 0; //红
}
else if (tmp < 128)
{
dst.at<Vec3b>(i, j)[0] = (127 - tmp) * 4;
dst.at<Vec3b>(i, j)[1] = 255;
dst.at<Vec3b>(i, j)[2] = 0;
}
else if (tmp < 192)
{
dst.at<Vec3b>(i, j)[0] = 0;
dst.at<Vec3b>(i, j)[1] = 255;
dst.at<Vec3b>(i, j)[2] = (tmp - 127) * 4;
}
else
{
dst.at<Vec3b>(i, j)[0] = 0;
dst.at<Vec3b>(i, j)[1] = (255 - tmp) * 4;
dst.at<Vec3b>(i, j)[2] = 255;
}
}
}
break;
default:
break;
}
imshow("伪彩色增强", dst);
}
void CDIP182002108Dlg::OnBnClickedSmooth()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_kemalSize <= 0 || m_kemalSize%2==0)
{
AfxMessageBox(_T("窗口大小错误!"));
return;
}
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), CV_8UC3);
switch (m_filterType)
{
case 0: //均值滤波
blur(g_src, dst, Size(m_kemalSize, m_kemalSize));
imshow("均值滤波", dst);
break;
case 1: //中值滤波
medianBlur(g_src, dst, m_kemalSize);
imshow("中值滤波", dst);
break;
case 2: //高斯滤波
GaussianBlur(g_src, dst, Size(m_kemalSize, m_kemalSize), 0, 0);
imshow("高斯滤波", dst);
break;
default:
break;
}
}
void CDIP182002108Dlg::OnBnClickedSharp()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), CV_8UC3);
Mat grad_x, grad_y, abs_grad_x, abs_grad_y, grad;
Mat kernal;
switch (m_sharpType)
{
case 0:
//x方向梯度
Sobel(g_src, grad_x, CV_16S, 1, 0, 3, 1, 0, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);
//y方向梯度
Sobel(g_src, grad_y, CV_16S, 1, 0, 3, 1, 0, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y);
//合并梯度
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
imshow("Sobel", dst);
break;
case 1:
Laplacian(g_src, grad, CV_16S, 3, 1, 0, BORDER_DEFAULT);
convertScaleAbs(grad, dst);
imshow("Laplacian", dst);
break;
case 2:
kernal = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(g_src, dst, CV_8UC1, kernal);
imshow("自定义Laplacian", dst);
break;
default:
break;
}
}
void CDIP182002108Dlg::OnBnClickedThre()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_th<0||m_th>255)
{
AfxMessageBox(_T("阈值设定错误!"));
return;
}
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), CV_8UC3);
threshold(g_src, dst, m_th, 255, CV_THRESH_BINARY);
imshow("固定阈值", dst);
}
void CDIP182002108Dlg::OnBnClickedAdthre()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_kernalSize % 2 == 0)
{
m_kernalSize++;
}
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst.create(src.size(), CV_8UC3);
adaptiveThreshold(g_src, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, m_kernalSize, m_bias);
imshow("动态阈值", dst);
}
void CDIP182002108Dlg::OnBnClickedRegoingrow()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_seedX<0 || m_seedX>(src.rows - 1) || m_seedY<0 || m_seedY>(src.cols - 1))
{
AfxMessageBox(_T(""));
return;
}
Mat g_src, dst;
cvtColor(src, g_src, CV_BGR2GRAY);
dst = Mat::zeros(g_src.size(), CV_8UC1);
Point2i pt(m_seedY, m_seedX); //种子点
int th = m_regionTh;
Point2i ptGrowing; //待生长点坐标
int nGrowlabel = 0; //标记是否过生长
int nSrcValue = 0; //生长起点灰度
int nCurValue = 0; //当前生长点的灰度值
int DIR[8][2] = { {-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1} }; //8邻域
std::vector<Point2i> vcGrowPt; //生长点栈
vcGrowPt.push_back(pt); //种子点入栈
dst.at<uchar>(pt.y, pt.x) = 255;
nSrcValue = g_src.at<uchar>(pt.y, pt.x); //记录种子点的灰度值
while (!vcGrowPt.empty())
{
pt = vcGrowPt.back(); //取生长点
vcGrowPt.pop_back();
//判断8邻域点是否生长
for (int i = 0; i < 8; i++)
{
ptGrowing.x = pt.x + DIR[i][0];
ptGrowing.y = pt.y + DIR[i][1];
if (ptGrowing.x<0 || ptGrowing.x>(src.rows - 1) || ptGrowing.y<0 || ptGrowing.y>(src.cols - 1))
{
continue;
}
nGrowlabel = dst.at<uchar>(ptGrowing.y, ptGrowing.x);
if (nGrowlabel == 0)
{
nCurValue = g_src.at<uchar>(ptGrowing.y, ptGrowing.x);
if (abs(nCurValue - nSrcValue) < th)
{
dst.at<uchar>(ptGrowing.y, ptGrowing.x) = 255; //满足条件,设置为白色
vcGrowPt.push_back(ptGrowing); //生长点入栈
}
}
}
}
imshow("区域生长法", dst);
}
void CDIP182002108Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_seedX<0 || m_seedX>(src.rows - 1) || m_seedY<0 || m_seedY>(src.cols - 1))
{
AfxMessageBox(_T(""));
return;
}
Mat dst;
dst = src.clone();
Point2i pt(m_fSeedY, m_fSeedX); //种子点
int th = m_fTh;
Rect coomp;
floodFill(dst, pt, Scalar(255, 0, 255), &coomp, Scalar(th, th, th), Scalar(th, th, th));
imshow("漫水分割", dst);
}
void CDIP182002108Dlg::OnBnClickedErode()
{
// TODO: 在此添加控件通知处理程序代码
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_morphSize % 2 == 0) {
m_morphSize += 1;
}
else if (m_morphSize <= 0)
{
AfxMessageBox(_T("结构元尺寸不能小于零!"));
return;
}
Mat dst, g_src;
threshold(src, g_src, 125, 252, THRESH_BINARY);
int shape, kSize = m_morphSize;
//kSize = 2 * m_morphSize + 1;
switch (m_morphType)
{
case 0:
shape = MORPH_RECT;
break;
case 1:
shape = MORPH_ELLIPSE;
break;
case 2:
shape = MORPH_CROSS;
break;
default:
return;
break;
}
Mat kernel = getStructuringElement(shape, Size(kSize, kSize), Point(-1, -1));
erode(g_src, dst, kernel);
imshow("腐蚀", dst);
}
void CDIP182002108Dlg::OnBnClickedDilate()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_morphSize % 2 == 0) {
m_morphSize += 1;
}
else if (m_morphSize <= 0)
{
AfxMessageBox(_T("结构元尺寸不能小于零!"));
return;
}
Mat dst, g_src;
threshold(src, g_src, 125, 252, THRESH_BINARY);
int shape, kSize = m_morphSize;
//kSize = 2 * m_morphSize + 1;
switch (m_morphType)
{
case 0:
shape = MORPH_RECT;
break;
case 1:
shape = MORPH_ELLIPSE;
break;
case 2:
shape = MORPH_CROSS;
break;
default:
return;
break;
}
Mat kernel = getStructuringElement(shape, Size(kSize, kSize), Point(-1, -1));
dilate(g_src, dst, kernel);
imshow("膨胀", dst);
}
void CDIP182002108Dlg::OnBnClickedMorphopen()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_morphSize % 2 == 0) {
m_morphSize += 1;
}
else if (m_morphSize <= 0)
{
AfxMessageBox(_T("结构元尺寸不能小于零!"));
return;
}
Mat dst, g_src;
threshold(src, g_src, 125, 252, THRESH_BINARY);
int shape, kSize = m_morphSize;
//kSize = 2 * m_morphSize + 1;
switch (m_morphType)
{
case 0:
shape = MORPH_RECT;
break;
case 1:
shape = MORPH_ELLIPSE;
break;
case 2:
shape = MORPH_CROSS;
break;
default:
return;
break;
}
Mat kernel = getStructuringElement(shape, Size(kSize, kSize), Point(-1, -1));
morphologyEx(g_src, dst, MORPH_OPEN, kernel);
imshow("开运算", dst);
}
void CDIP182002108Dlg::OnBnClickedMorphclose()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
if (m_morphSize % 2 == 0) {
m_morphSize += 1;
}
else if (m_morphSize <= 0)
{
AfxMessageBox(_T("结构元尺寸不能小于零!"));
return;
}
Mat dst,g_src;
threshold(src, g_src, 125, 252, THRESH_BINARY);
int shape, kSize = m_morphSize;
//kSize = 2 * m_morphSize + 1;
switch (m_morphType)
{
case 0:
shape = MORPH_RECT;
break;
case 1:
shape = MORPH_ELLIPSE;
break;
case 2:
shape = MORPH_CROSS;
break;
default:
return;
break;
}
Mat kernel = getStructuringElement(shape, Size(kSize, kSize), Point(-1, -1));
morphologyEx(g_src, dst, MORPH_CLOSE, kernel);
imshow("闭运算", dst);
}
void CDIP182002108Dlg::OnBnClickedColor()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
UpdateData(TRUE);
Mat dst;
int code;
String caption = "";
switch (m_colorType)
{
case 0:
code = COLOR_BGR2HSV;
caption = "BGR->HSV";
break;
case 1:
code = COLOR_BGR2XYZ;
caption = "BGR->XYZ";
break;
case 2:
code = COLOR_BGR2YCrCb;
caption = "BGR->YCrCb";
default:
break;
}
cvtColor(src, dst, code);
imshow(caption, dst);
}
void CDIP182002108Dlg::OnBnClickedButton9()
{
// TODO: 在此添加控件通知处理程序代码
if (src.empty())
{
AfxMessageBox(_T("没有图片资源!"));
return;
}
Mat dst = src.clone();
//灰度世界法
std::vector<Mat> imageRGB;
//RGB三通道分离
split(dst, imageRGB);
//求原始图像的RGB分量的均值
double R, G, B;
B = mean(imageRGB[0])[0];
G = mean(imageRGB[1])[0];
R = mean(imageRGB[2])[0];
//需要调整的RGB分量的增益
double KR, KG, KB;
KB = (R + G + B) / (3 * B);
KG = (R + G + B) / (3 * G);
KR = (R + G + B) / (3 * R);
//调整RGB三个通道各自的值
imageRGB[0] = imageRGB[0] * KB;
imageRGB[1] = imageRGB[1] * KG;
imageRGB[2] = imageRGB[2] * KR;
//RGB三通道图像合并
merge(imageRGB, dst);
imshow("白平衡调整", dst);
}