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
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);
|
|
}
|