(原創) 如何使用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
5using namespace System::Drawing;
6using namespace System::Drawing::Imaging;
7
8typedef std::pair<int, int> MyPoint;
9typedef std::vector<MyPoint> MyPointVec;
10typedef int GrayLevel;
11
12// Make kernel by radius
13MyPointVec makeKernel(const int&);
14// Process erosion
15Bitmap^ erosion(Bitmap^, const MyPointVec%);
16// Get min gray level by kernel
17GrayLevel getMinByKernel(Bitmap^, const MyPointVec%, const MyPoint%);
18// Get gray level from Color object
19GrayLevel getGrayLevelFromColor(Color^);
20
21int 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
36MyPointVec 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
84Bitmap^ 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
100GrayLevel 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
124GrayLevel getGrayLevelFromColor(Color^ color) {
125 return (color->R + color->G + color->B) /3;
126}
2#include <vector>
3#include <algorithm>
4
5using namespace System::Drawing;
6using namespace System::Drawing::Imaging;
7
8typedef std::pair<int, int> MyPoint;
9typedef std::vector<MyPoint> MyPointVec;
10typedef int GrayLevel;
11
12// Make kernel by radius
13MyPointVec makeKernel(const int&);
14// Process erosion
15Bitmap^ erosion(Bitmap^, const MyPointVec%);
16// Get min gray level by kernel
17GrayLevel getMinByKernel(Bitmap^, const MyPointVec%, const MyPoint%);
18// Get gray level from Color object
19GrayLevel getGrayLevelFromColor(Color^);
20
21int 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
36MyPointVec 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
84Bitmap^ 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
100GrayLevel 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
124GrayLevel 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?