高级程序语言课程设计&&MFC&&opencv&&并行计算openmp

又到一学期期末课程设计周
计科小学生又来发布课程设计

本次是高级程序设计
用MFC构建界面,调用opencv动态链接库,再加上openmp实现并行计算。
看起来高大上很多。

提示
如果要使用openmp要在配置中打开
在这里插入图片描述

业务流程大致如此:
在这里插入图片描述
高斯滤波:
在这里插入图片描述
伪色彩增强:
在这里插入图片描述
在进行线性增强和灰度处理时可以选择多线程处理来缩减响应时间
,分别以2线程和8线程展示:

在这里插入图片描述
在这里插入图片描述
代码部分细节:

点击打开图片按钮响应对应的代码细节展示:
点击“确定”按钮后获取文件路径到strPathName,并将文件路径显示到编辑框

if (dlg.DoModal() == IDOK) 
	{
		strPathName = dlg.GetPathName();
		m_file.SetWindowText(strPathName); 
	}

使用StretchDIBits函数显示图片

StretchDIBits(GetDlgItem(IDC_STATIC)->GetDC()->GetSafeHdc()
			, 0, 0, std::min(rect.Width(), rect.Height()), std::min(rect.Width(), rect.Height())
			, 0, 0, cvImgTmp.cols, cvImgTmp.rows,
			cvImgTmp.data, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);

声明图片大小

        bmiHeader = &bitmapInfo.bmiHeader;
		bmiHeader->biSize = sizeof(BITMAPINFOHEADER);
		bmiHeader->biWidth = cvImgTmp.cols;
		bmiHeader->biHeight = -cvImgTmp.rows;
		bmiHeader->biPlanes = 1;
		bmiHeader->biBitCount = 24;
		bmiHeader->biCompression = BI_RGB;
		bitmapInfo.bmiHeader.biSizeImage = 0;
		bmiHeader->biXPelsPerMeter = GetSystemMetrics(SM_CXSCREEN);
		bmiHeader->biYPelsPerMeter = GetSystemMetrics(SM_CYSCREEN);
		bmiHeader->biClrUsed = 0;
		bmiHeader->biClrImportant = 0;

使用IsIconic函数来判断当前界面是否已经有图像打开
若没有则按照路径打开图片,若已存在图片
使用CPaintDC函数对当前图层关闭,然后再显示选中图片

if (IsIconic())//IsIconic()作用是判断窗口是否处于最小化状态(点击了最小化按钮之后
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);//窗口调用窗口程序

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);//窗体显示区域的宽度和高度、滚动条的宽度和高度
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);//GetClientRect用于取得指定窗口的客户区域大小
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}

对图片进行高斯滤波处理

if (str == "")
	{
		AfxMessageBox(_T("请先打开图片!"));
		return;
	}
	Mat image = imread(str, 1);
	Mat out;
	//进行滤波操作
	GaussianBlur(image, out, Size(9, 9), 10, 0);//X方向上的高斯核标准偏差;
	imwrite("高斯滤波.jpg", image);
	waitKey();

点击伪色彩增强

if (str == "")
	{
		AfxMessageBox(_T("请先打开图片!"));
		return;
	}


	Mat im_gray = imread(str, 1);
	Mat im_color;
	applyColorMap(im_gray, im_color, COLORMAP_JET);
	imwrite("伪彩色增强.jpg", im_color);
	waitKey(0);

对图像进行腐蚀操作

if (str == "")
	{
		AfxMessageBox(_T("请先打开图片!"));
		return;
	}
	Mat src = imread(str, 1);
	Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
	Mat dsImage;
	erode(src, dsImage, element);
	imwrite("腐蚀操作.jpg", dsImage);
	waitKey(0);

对图片进行线性增强
分别使用三个通道存储之前的图像RGB色彩信息,然后使用saturate_cast函数对图片进行线性处理,如果图片位灰度图片则只使用一个变量来存储色阶信息。

if (str == "")
	{
		AfxMessageBox(_T("请先打开图片!"));
		return;
	}
	Mat src1, dst;
	src1 = imread(str,1);
	double alpha = 1.2, beta = 50;
	dst = Mat::zeros(src1.size(), src1.type());
	Mat src2 = src1, dst1 = dst;
	float begintime = omp_get_wtime();
	for (int row = 0; row < src1.rows; row++)
	{
		for (int col = 0; col < src1.cols; col++)
		{
			if (src1.channels() == 3)
			{
				int b = src1.at<Vec3b>(row, col)[0];
				int g = src1.at<Vec3b>(row, col)[1];
				int r = src1.at<Vec3b>(row, col)[2];

				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
			}
			else if (src1.channels() == 1)
			{
				float v = src1.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
			}
		}
	}
	float endtime = omp_get_wtime();
	float before = endtime - begintime;

使用多线程加速处理。
使用omp parallel for num_threads(n)语句来进行多线程加速,n为输入的线程数,最后减去初始的时间得到多线程加速后节约的时间。

begintime = omp_get_wtime();
#pragma omp parallel for num_threads(n)
	for (int row = 0; row < src2.rows; row++)
	{
		for (int col = 0; col < src2.cols; col++)
		{
			if (src2.channels() == 3)
			{
				int b = src2.at<Vec3b>(row, col)[0];
				int g = src2.at<Vec3b>(row, col)[1];
				int r = src2.at<Vec3b>(row, col)[2];

				dst1.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
				dst1.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);
				dst1.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
			}
			else if (src2.channels() == 1)
			{
				float v = src2.at<uchar>(row, col);
				dst1.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
			}
		}
	}
	endtime = omp_get_wtime();
	float after = endtime - begintime;
	float gap = before - after;

对图片进行灰度处理
使用max函数将图像原本的rgb信息压缩成一个通道

dst.create(src.size(), src.type());
	Mat src1 = src, dst1 = dst;
	float begintime = omp_get_wtime();
	for (int row = 0; row < src.rows; row++)

	{
		for (int col = 0; col < src.cols; col++)

		{

			int b = src.at<Vec3b>(row, col)[0];

			int g = src.at<Vec3b>(row, col)[1];

			int r = src.at<Vec3b>(row, col)[2];

			dst.at<Vec3b>(row, col)[0] = max(r, max(g, b));

			dst.at<Vec3b>(row, col)[1] = max(r, max(g, b));

			dst.at<Vec3b>(row, col)[2] = max(r, max(g, b));
		}
	}
	float endtime = omp_get_wtime();
	float before = endtime - begintime;

使用omp parallel for num_threads(n)进行多线程加速处理

	begintime = omp_get_wtime();
#pragma omp parallel for num_threads(n)
	for (int row = 0; row < src1.rows; row++)

	{
		for (int col = 0; col < src1.cols; col++)

		{

			int b = src1.at<Vec3b>(row, col)[0];

			int g = src1.at<Vec3b>(row, col)[1];

			int r = src1.at<Vec3b>(row, col)[2];

			dst1.at<Vec3b>(row, col)[0] = max(r, max(g, b));

			dst1.at<Vec3b>(row, col)[1] = max(r, max(g, b));

			dst1.at<Vec3b>(row, col)[2] = max(r, max(g, b));
		}
	}
	endtime = omp_get_wtime();
	float after = endtime - begintime;
	float gap = before - after;
	

以上就是整体框架了

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
膨胀和腐蚀是OpenCV中的基本形态学操作。膨胀是使用像素邻域内的局部极大运算来膨胀一张图片,而腐蚀则是使用像素邻域内的局部极小运算来腐蚀一张图片。这两个操作都是针对图像中的白色部分(高亮部分)进行的。在OpenCV中,可以使用dilate()函数进行膨胀操作,使用erode()函数进行腐蚀操作。函数的原型如下: void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue()); void erode(InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue()); 膨胀和腐蚀操作常用于二值化或灰度图像,可以用于噪声消除和特征处理。膨胀操作是通过与结构元素进行卷积计算,取局部极大值来替代中心值;而腐蚀操作则是取局部极小值来替换中心值。\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [OpenCV的膨胀和腐蚀](https://blog.csdn.net/m0_37360684/article/details/97534489)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [OpenCV.腐蚀与膨胀](https://blog.csdn.net/kicinio/article/details/121191134)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值