(原創) 如何使用C++/CLI对图片做Grayscale Erosion? (.NET) (C/C++) (C++/CLI) (GDI+) (Image Processing)
原理和Grayscale Dilation类似,只是Erosion是找minimun。
1
#include "stdafx.h"
2
#include <vector>
3
#include <algorithm>
4
5
using namespace System::Drawing;
6
using namespace System::Drawing::Imaging;
7
8
typedef std::pair<int, int> MyPoint;
9
typedef std::vector<MyPoint> MyPointVec;
10
typedef int GrayLevel;
11
12
// Make kernel by radius
13
MyPointVec makeKernel(const int&);
14
// Process erosion
15
Bitmap^ erosion(Bitmap^, const MyPointVec%);
16
// Get min gray level by kernel
17
GrayLevel getMinByKernel(Bitmap^, const MyPointVec%, const MyPoint%);
18
// Get gray level from Color object
19
GrayLevel getGrayLevelFromColor(Color^);
20
21
int main() {
22
// Read image from lena.jpg
23
Bitmap^ image = gcnew Bitmap("lena.jpg");
24
const int radius = 2;
25
// Make kernel by radius
26
MyPointVec kernel = makeKernel(radius);
27
// New eroded image
28
Bitmap^ newImage = erosion(image, kernel);
29
// Save new eroded image to disk
30
newImage->Save("GrayscaleErodedLena.jpg");
31
32
return 0;
33
}
34
35
// Make kernel by radius
36
MyPointVec makeKernel(const int& radius) {
37
MyPointVec kernel;
38
39
if (radius == 0) {
40
kernel.push_back(std::make_pair(0,0));
41
}
42
else if (radius == 1) {
43
// *
44
// ***
45
// *
46
kernel.push_back(std::make_pair(0,0));
47
kernel.push_back(std::make_pair(1,0));
48
kernel.push_back(std::make_pair(0,1));
49
kernel.push_back(std::make_pair(-1,0));
50
kernel.push_back(std::make_pair(0,-1));
51
}
52
else {
53
kernel.push_back(std::make_pair(-1,2));
54
kernel.push_back(std::make_pair(0,2));
55
kernel.push_back(std::make_pair(1,2));
56
57
kernel.push_back(std::make_pair(-2,1));
58
kernel.push_back(std::make_pair(-1,1));
59
kernel.push_back(std::make_pair(0,1));
60
kernel.push_back(std::make_pair(1,1));
61
kernel.push_back(std::make_pair(2,1));
62
63
kernel.push_back(std::make_pair(-2,0));
64
kernel.push_back(std::make_pair(-1,0));
65
kernel.push_back(std::make_pair(0,0));
66
kernel.push_back(std::make_pair(1,0));
67
kernel.push_back(std::make_pair(2,0));
68
69
kernel.push_back(std::make_pair(-2,-1));
70
kernel.push_back(std::make_pair(-1,-1));
71
kernel.push_back(std::make_pair(0,-1));
72
kernel.push_back(std::make_pair(1,-1));
73
kernel.push_back(std::make_pair(2,-1));
74
75
kernel.push_back(std::make_pair(-1,-2));
76
kernel.push_back(std::make_pair(0,-2));
77
kernel.push_back(std::make_pair(1,-2));
78
}
79
80
return kernel;
81
}
82
83
// Process erosion
84
Bitmap^ erosion(Bitmap^ image, const MyPointVec% kernel) {
85
// New dilated image
86
Bitmap^ newImage = gcnew Bitmap(image->Width, image->Height);
87
for(int x = 0; x != image->Width; ++x) {
88
for(int y = 0; y != image->Height; ++y) {
89
// Get max gray level by kernel
90
GrayLevel gray = getMinByKernel(image, kernel, std::make_pair(x,y));
91
// Set max gray level to new dilated image
92
newImage->SetPixel(x, y, Color::FromArgb(gray, gray, gray));
93
}
94
}
95
96
return newImage;
97
}
98
99
// Get min gray level by kernel
100
GrayLevel getMinByKernel(Bitmap^ image, const MyPointVec% kernel, const MyPoint% point) {
101
typedef std::vector<GrayLevel> NeighborColor;
102
NeighborColor neighborColor;
103
104
// C++/CLI's new for each syntax
105
for each (MyPoint kpoint in kernel) {
106
int x = point.first + kpoint.first;
107
int y = point.second + kpoint.second;
108
if (x >= 0 && x < image->Width) {
109
if (y >= 0 && y < image->Height) {
110
GrayLevel gray = getGrayLevelFromColor(image->GetPixel(x, y));
111
// push_back new gray level to vector
112
neighborColor.push_back(gray);
113
}
114
}
115
}
116
117
// Use STL min_element() algorithm to get max gray level
118
NeighborColor::iterator minIter = min_element(neighborColor.begin(), neighborColor.end());
119
120
return *minIter;
121
}
122
123
// Get gray level from Color object
124
GrayLevel getGrayLevelFromColor(Color^ color) {
125
return (color->R + color->G + color->B) /3;
126
}
#include "stdafx.h"2
#include <vector>3
#include <algorithm>4

5
using namespace System::Drawing;6
using namespace System::Drawing::Imaging;7

8
typedef std::pair<int, int> MyPoint;9
typedef std::vector<MyPoint> MyPointVec;10
typedef int GrayLevel;11

12
// Make kernel by radius13
MyPointVec makeKernel(const int&);14
// Process erosion15
Bitmap^ erosion(Bitmap^, const MyPointVec%); 16
// Get min gray level by kernel17
GrayLevel getMinByKernel(Bitmap^, const MyPointVec%, const MyPoint%);18
// Get gray level from Color object19
GrayLevel getGrayLevelFromColor(Color^);20

21
int main() {22
// Read image from lena.jpg23
Bitmap^ image = gcnew Bitmap("lena.jpg");24
const int radius = 2;25
// Make kernel by radius26
MyPointVec kernel = makeKernel(radius);27
// New eroded image28
Bitmap^ newImage = erosion(image, kernel);29
// Save new eroded image to disk30
newImage->Save("GrayscaleErodedLena.jpg");31

32
return 0;33
}34

35
// Make kernel by radius36
MyPointVec makeKernel(const int& radius) {37
MyPointVec kernel;38

39
if (radius == 0) {40
kernel.push_back(std::make_pair(0,0));41
}42
else if (radius == 1) {43
// *44
// ***45
// *46
kernel.push_back(std::make_pair(0,0));47
kernel.push_back(std::make_pair(1,0));48
kernel.push_back(std::make_pair(0,1));49
kernel.push_back(std::make_pair(-1,0));50
kernel.push_back(std::make_pair(0,-1));51
}52
else {53
kernel.push_back(std::make_pair(-1,2));54
kernel.push_back(std::make_pair(0,2));55
kernel.push_back(std::make_pair(1,2));56

57
kernel.push_back(std::make_pair(-2,1));58
kernel.push_back(std::make_pair(-1,1));59
kernel.push_back(std::make_pair(0,1));60
kernel.push_back(std::make_pair(1,1));61
kernel.push_back(std::make_pair(2,1));62

63
kernel.push_back(std::make_pair(-2,0));64
kernel.push_back(std::make_pair(-1,0));65
kernel.push_back(std::make_pair(0,0));66
kernel.push_back(std::make_pair(1,0));67
kernel.push_back(std::make_pair(2,0));68

69
kernel.push_back(std::make_pair(-2,-1));70
kernel.push_back(std::make_pair(-1,-1));71
kernel.push_back(std::make_pair(0,-1));72
kernel.push_back(std::make_pair(1,-1));73
kernel.push_back(std::make_pair(2,-1));74

75
kernel.push_back(std::make_pair(-1,-2));76
kernel.push_back(std::make_pair(0,-2));77
kernel.push_back(std::make_pair(1,-2));78
}79

80
return kernel;81
}82

83
// Process erosion 84
Bitmap^ erosion(Bitmap^ image, const MyPointVec% kernel) {85
// New dilated image86
Bitmap^ newImage = gcnew Bitmap(image->Width, image->Height);87
for(int x = 0; x != image->Width; ++x) {88
for(int y = 0; y != image->Height; ++y) {89
// Get max gray level by kernel90
GrayLevel gray = getMinByKernel(image, kernel, std::make_pair(x,y));91
// Set max gray level to new dilated image92
newImage->SetPixel(x, y, Color::FromArgb(gray, gray, gray));93
}94
}95

96
return newImage;97
}98

99
// Get min gray level by kernel100
GrayLevel getMinByKernel(Bitmap^ image, const MyPointVec% kernel, const MyPoint% point) {101
typedef std::vector<GrayLevel> NeighborColor;102
NeighborColor neighborColor;103

104
// C++/CLI's new for each syntax105
for each (MyPoint kpoint in kernel) {106
int x = point.first + kpoint.first;107
int y = point.second + kpoint.second;108
if (x >= 0 && x < image->Width) {109
if (y >= 0 && y < image->Height) {110
GrayLevel gray = getGrayLevelFromColor(image->GetPixel(x, y));111
// push_back new gray level to vector112
neighborColor.push_back(gray);113
}114
}115
}116

117
// Use STL min_element() algorithm to get max gray level118
NeighborColor::iterator minIter = min_element(neighborColor.begin(), neighborColor.end());119

120
return *minIter;121
}122

123
// Get gray level from Color object124
GrayLevel getGrayLevelFromColor(Color^ color) {125
return (color->R + color->G + color->B) /3;126
}原图

执行结果
See Also
如何使用C++/CLI对图片做Grayscale Dilation?
如何使用C++/CLI对图片做Grayscale Opening?
如何使用C++/CLI对图片做Grayscale Closing?


浙公网安备 33010602011771号