我是靠谱客的博主 个性春天,最近开发中收集的这篇文章主要介绍形态学操作——腐蚀膨胀、开闭运算、顶帽变换底帽变换 c++实现腐蚀膨胀开运算闭运算Trackbar使用顶帽变换黑帽变换trackbar使用举例,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
腐蚀
卷积核沿着图像滑动,像素值为卷积核范围里的最小值。腐蚀之后图像会变暗。
opencv实现
//第一个参数MORPH_RECT表示矩形的卷积核,还有椭圆形的、交叉型的
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//腐蚀操作
erode(img, out, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)
/*src:输入图像
dst:目标图像
kernel:結構元素,如果kernel=Mat()則為預設的3×3矩形,越大腐蚀效果越明显。
anchor:原點位置,預設為結構元素的中央。
iterations:執行次數,預設為1次。*/
c++实现
void my_erode(Mat src, Mat dst, int x, int y) {
if ((x % 2 == 1) && (y % 2 == 1)) {
//卷积核长宽需为奇数
int xx = x / 2;
int yy = y / 2;
for (int rows = yy; rows < src.rows - yy; rows++) {
for (int cols = xx; cols < src.cols - xx; cols++) {
int my_min = 255;
for (int i = rows - yy; i < rows + yy + 1; i++) {
for (int j = cols - xx; j < cols + xx + 1; j++) {
my_min = MIN(my_min, src.at<uchar>(i, j));
}
}
dst.at<uchar>(rows, cols) = my_min;
}
}
}
}
膨胀
卷积核沿着图像滑动,像素值为卷积核范围里的最大值,膨胀后图像会变亮。
opencv实现
//第一个参数MORPH_RECT表示矩形的卷积核,还有椭圆形的、交叉型的
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//膨胀操作
dilate(img, out, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)
/*src:输入图像
dst:目标图像
kernel:結構元素,如果kernel=Mat()則為預設的3×3矩形,越大膨胀效果越明显。
anchor:原點位置,預設為結構元素的中央。
iterations:執行次數,預設為1次。*/
c++实现
void my_dilate(Mat src, Mat dst, int x, int y) {
if ((x % 2 == 1) && (y % 2 == 1)) {
//卷积核长宽需为奇数
int xx = x / 2;
int yy = y / 2;
for (int rows = yy; rows < src.rows - yy; rows++) {
for (int cols = xx; cols < src.cols - xx; cols++) {
int my_max = 0
for (int i = rows - yy; i < rows + yy + 1; i++) {
for (int j = cols - xx; j < cols + xx + 1; j++) {
my_max = MAX(my_max, src.at<uchar>(i, j));
}
}
dst.at<uchar>(rows, cols) = my_max;
}
}
}
}
开运算
开运算 = 先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了)
开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不便。
opencv实现
Mat element = getStructuringElement(MORPH_RECT, Size(18, 18));
//具体要选择哪种操作,就修改第三个参数就可以了。这里演示的是形态学开运算处理
morphologyEx(img, out, MORPH_OPEN, element);
//腐蚀和膨胀也可以调用此模板
/*MORPH_OPEN 开运算
MORPH_CLOSE 闭运算
MORPH_ERODE 腐蚀
MORPH_DILATE 膨胀*/
c++实现
void my_open(Mat src, Mat dst, int x, int y) {
Mat dst1;
src.copyTo(dst1);
my_erode(src, dst1, x, y);
my_dilate(dst1, dst, x, y);
}
闭运算
闭运算 = 先膨胀运算,再腐蚀运算(看上去将两个细微连接的图块封闭在一起)
闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
c++实现
void my_close(Mat src, Mat dst, int x, int y) {
Mat dst1;
dst.copyTo(dst1);
my_dilate(src, dst1, x, y);
my_erode(dst1, dst, x, y);
}
Trackbar使用
只以开运算为例:
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat img, oimg;//为了方便定义为全局变量(这是一个不好的习惯)
int width = 1;
int hight = 1;
void my_dilate(Mat src, Mat dst, int x, int y) {
if ((x % 2 == 1) && (y % 2 == 1)) {
int xx = x / 2;
int yy = y / 2;
int rows, cols;
for (rows = yy; rows < src.rows - yy; rows++) {
for (cols = xx; cols < src.cols - xx; cols++) {
int my_max = 0;
for (int i = rows - yy; i < rows + yy + 1; i++) {
for (int j = cols - xx; j < cols + xx + 1; j++) {
my_max = MAX(my_max, src.at<uchar>(i, j));
}
}
dst.at<uchar>(rows, cols) = my_max;
}
}
}
}
void my_erode(Mat src, Mat dst, int x, int y) {
if ((x % 2 == 1) && (y % 2 == 1)) {
int xx = x / 2;
int yy = y / 2;
for (int rows = yy; rows < src.rows - yy; rows++) {
for (int cols = xx; cols < src.cols - xx; cols++) {
int my_min = 255;
for (int i = rows - yy; i < rows + yy + 1; i++) {
for (int j = cols - xx; j < cols + xx + 1; j++) {
my_min = MIN(my_min, src.at<uchar>(i, j));
}
}
dst.at<uchar>(rows, cols) = my_min;
}
}
}
}
void my_open(Mat src, Mat dst, int x, int y) {
Mat dst1;
src.copyTo(dst1);
my_erode(src, dst1, x, y);
my_dilate(dst1, dst, x, y);
}
void open_track(int, void*) {
my_open(img, oimg, 2 * width + 1, 2 * hight + 1);
imshow("开运算", oimg);
}
int main()
{
img = imread("C:/Users/45374/Desktop/code/img/lina320.bmp");
if (img.channels() == 3) {
cvtColor(img, img, CV_BGR2GRAY);
}
img.copyTo(oimg);
img.copyTo(oimg2);
namedWindow("开运算");
createTrackbar("x:", "trackbar", &width, 10, open_track);
createTrackbar("y:", "trackbar", &hight, 10, open_track);
open_track(0, 0);
waitKey();
return 0;
}
效果如下:
顶帽变换
顶帽变换=原图减去开运算。如果再与原图相加可增强轮廓。
opencv实现:
Mat element = getStructuringElement(MORPH_RECT, Size(8, 8));
morphologyEx(img, out, MORPH_TOPHAT, element);
c++实现:
void my_tophat(Mat src, Mat dst, int x, int y) {
Mat dst1;
src.copyTo(dst1);
my_open(src, dst1, x, y);
imshow("open", dst1);
for (int rows = 0; rows < src.rows; rows++) {
for (int cols = 0; cols < src.cols; cols++) {
dst.at<uchar>(rows, cols) = saturate_cast<uchar>(src.at<uchar>(rows, cols) - dst1.at<uchar>(rows, cols));
}
}
namedWindow("顶帽", CV_WINDOW_AUTOSIZE);
imshow("顶帽", dst);
}
效果如下:
黑帽变换
黑帽变换(又叫底帽变换)=闭运算减去原图。如果再与原图相加可模糊噪声。
opencv实现:
Mat element = getStructuringElement(MORPH_RECT, Size(18, 18));
//具体要选择哪种操作,就修改第三个参数就可以了。这里演示的是形态学黑帽变换
morphologyEx(img, out, MORPH_BLACKHAT, element);
c++实现:
void my_underhat(Mat src, Mat dst, int x, int y) {
Mat dst1;
src.copyTo(dst1);
my_close(src, dst1, x, y);
imshow("colse", dst1);
for (int rows = 0; rows < src.rows; rows++) {
for (int cols = 0; cols < src.cols; cols++) {
dst.at<uchar>(rows, cols) = saturate_cast<uchar>(dst1.at<uchar>(rows, cols) - src.at<uchar>(rows, cols));
}
}
namedWindow("底帽", CV_WINDOW_AUTOSIZE);
imshow("底帽", dst);
}
trackbar使用举例
#include "pch.h"
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
const char* WINDOW_NAME = "处理后";
Mat img, oimg;
int width = 1;
int hight = 1;
void on_track(int, void*) {
Mat element = getStructuringElement(MORPH_RECT, Size(2 * width + 1, 2 * hight + 1));
//进行形态学操作
morphologyEx(img, oimg, MORPH_TOPHAT, element);
addWeighted(img, 1, oimg, 1,0, oimg2);//顶帽变换后加上原图,增强纹理和边界
imshow(WINDOW_NAME, oimg);
}
int main()
{
img = imread("C:/Users/45374/Desktop/code/img/lena.jpg",1);
img.copyTo(oimg);
namedWindow(WINDOW_NAME);
createTrackbar("x:", WINDOW_NAME, &width, 10, on_track);
createTrackbar("y:", WINDOW_NAME, &hight, 10, on_track);
on_track(0, 0);
imshow(WINDOW_NAME, img);
waitKey(0);
return 0;
}
效果如下:
最后
以上就是个性春天为你收集整理的形态学操作——腐蚀膨胀、开闭运算、顶帽变换底帽变换 c++实现腐蚀膨胀开运算闭运算Trackbar使用顶帽变换黑帽变换trackbar使用举例的全部内容,希望文章能够帮你解决形态学操作——腐蚀膨胀、开闭运算、顶帽变换底帽变换 c++实现腐蚀膨胀开运算闭运算Trackbar使用顶帽变换黑帽变换trackbar使用举例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复