如何使用C++/CLI对图片做Grayscale Opening? (.NET) (C/C++) (C++/CLI) (GDI+) (Image Processing)

Opening的算法是:先对图片做Erosion,将结果再做Dilation,其目的在消除影像中的小杂点。

  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 opening
 15 Bitmap ^  opening(Bitmap ^ const  MyPointVec % );
 16 //  Process dilation 
 17 Bitmap ^  dilation(Bitmap ^ const  MyPointVec % ); 
 18 //  Process erosion
 19 Bitmap ^  erosion(Bitmap ^ const  MyPointVec % ); 
 20 //  Get max gray level by kernel
 21 GrayLevel getMaxByKernel(Bitmap ^ const  MyPointVec % const  MyPoint % );
 22 //  Get max gray level by kernel
 23 GrayLevel getMinByKernel(Bitmap ^ const  MyPointVec % const  MyPoint % );
 24 //  Get gray level from Color object
 25 GrayLevel getGrayLevelFromColor(Color ^ );
 26
 27 int  main()  {
 28  // Read image from lena.jpg
 29  Bitmap^ image = gcnew Bitmap("lena.jpg");
 30  const int radius = 2;
 31  // Make kernel by radius
 32  MyPointVec kernel = makeKernel(radius);
 33  // New dilated image
 34  Bitmap^ newImage = opening(image, kernel);
 35  // Save new dilated image to disk
 36  newImage->Save("GrayscaleOpening.jpg");
 37
 38  return 0;
 39}

 40
 41 //  Make kernel by radius
 42 MyPointVec makeKernel( const   int &  radius)  {
 43  MyPointVec kernel;
 44
 45  if (radius == 0{
 46    kernel.push_back(std::make_pair(0,0));
 47  }

 48  else if (radius == 1{
 49    //   *
 50    //  ***
 51    //   *
 52    kernel.push_back(std::make_pair(0,0));
 53    kernel.push_back(std::make_pair(1,0));
 54    kernel.push_back(std::make_pair(0,1));
 55    kernel.push_back(std::make_pair(-1,0));
 56    kernel.push_back(std::make_pair(0,-1));
 57  }

 58  else {
 59    kernel.push_back(std::make_pair(-1,2));
 60    kernel.push_back(std::make_pair(0,2));
 61    kernel.push_back(std::make_pair(1,2));
 62
 63    kernel.push_back(std::make_pair(-2,1));
 64    kernel.push_back(std::make_pair(-1,1));
 65    kernel.push_back(std::make_pair(0,1));
 66    kernel.push_back(std::make_pair(1,1));
 67    kernel.push_back(std::make_pair(2,1));
 68
 69    kernel.push_back(std::make_pair(-2,0));
 70    kernel.push_back(std::make_pair(-1,0));
 71    kernel.push_back(std::make_pair(0,0));
 72    kernel.push_back(std::make_pair(1,0));
 73    kernel.push_back(std::make_pair(2,0));
 74
 75    kernel.push_back(std::make_pair(-2,-1));
 76    kernel.push_back(std::make_pair(-1,-1));
 77    kernel.push_back(std::make_pair(0,-1));
 78    kernel.push_back(std::make_pair(1,-1));
 79    kernel.push_back(std::make_pair(2,-1));
 80
 81    kernel.push_back(std::make_pair(-1,-2));
 82    kernel.push_back(std::make_pair(0,-2));
 83    kernel.push_back(std::make_pair(1,-2));
 84  }

 85
 86  return kernel;
 87}

 88
 89 //  Process opening
 90 Bitmap ^  opening(Bitmap ^  image,  const  MyPointVec %  kernel)  {
 91  Bitmap^ newImage = dilation(erosion(image, kernel), kernel);
 92
 93  return newImage;
 94}

 95
 96 //  Process dilation 
 97 Bitmap ^  dilation(Bitmap ^  image,  const  MyPointVec %  kernel)  {
 98  // New dilated image
 99  Bitmap^ newImage = gcnew Bitmap(image->Width, image->Height);
100  for(int x = 0; x != image->Width; ++x) {
101    for(int y = 0; y != image->Height; ++y) {
102      // Get max gray level by kernel
103      GrayLevel gray = getMaxByKernel(image, kernel, std::make_pair(x,y));
104      // Set max gray level to new dilated image
105      newImage->SetPixel(x, y, Color::FromArgb(gray, gray, gray));
106    }

107  }

108
109  return newImage;
110}

111
112 //  Process erosion 
113 Bitmap ^  erosion(Bitmap ^  image,  const  MyPointVec %  kernel)  {
114  // New dilated image
115  Bitmap^ newImage = gcnew Bitmap(image->Width, image->Height);
116  for(int x = 0; x != image->Width; ++x) {
117    for(int y = 0; y != image->Height; ++y) {
118      // Get max gray level by kernel
119      GrayLevel gray = getMinByKernel(image, kernel, std::make_pair(x,y));
120      // Set max gray level to new dilated image
121      newImage->SetPixel(x, y, Color::FromArgb(gray, gray, gray));
122    }

123  }

124
125  return newImage;
126}

127
128
129 //  Get max gray level by kernel
130 GrayLevel getMaxByKernel(Bitmap ^  image,  const  MyPointVec %  kernel,  const  MyPoint %  point)  {
131  typedef std::vector<GrayLevel> NeighborColor;
132  NeighborColor neighborColor;
133
134  // C++/CLI's new for each syntax
135  for each (MyPoint kpoint in kernel) {
136    int x = point.first + kpoint.first;
137    int y = point.second + kpoint.second;
138    if (x >= 0 && x < image->Width) {
139      if (y >= 0 && y < image->Height) {
140        GrayLevel gray = getGrayLevelFromColor(image->GetPixel(x, y));
141        // push_back new gray level to vector
142        neighborColor.push_back(gray);
143      }

144    }

145  }

146
147  // Use STL max_element() algorithm to get max gray level
148  NeighborColor::iterator maxIter = max_element(neighborColor.begin(), neighborColor.end());
149
150  return *maxIter;
151}

152
153 //  Get min gray level by kernel
154 GrayLevel getMinByKernel(Bitmap ^  image,  const  MyPointVec %  kernel,  const  MyPoint %  point)  {
155  typedef std::vector<GrayLevel> NeighborColor;
156  NeighborColor neighborColor;
157
158  // C++/CLI's new for each syntax
159  for each (MyPoint kpoint in kernel) {
160    int x = point.first + kpoint.first;
161    int y = point.second + kpoint.second;
162    if (x >= 0 && x < image->Width) {
163      if (y >= 0 && y < image->Height) {
164        GrayLevel gray = getGrayLevelFromColor(image->GetPixel(x, y));
165        // push_back new gray level to vector
166        neighborColor.push_back(gray);
167      }

168    }

169  }

170
171  // Use STL min_element() algorithm to get max gray level
172  NeighborColor::iterator minIter = min_element(neighborColor.begin(), neighborColor.end());
173
174  return *minIter;
175}

176
177
178 //  Get gray level from Color object
179 GrayLevel getGrayLevelFromColor(Color ^  color)  {
180  return (color->+ color->+ color->B) /3;
181}

原图
 如何使用C++/CLI对图片做Grayscale Opening? (.NET) (C/C++) (C++/CLI) (GDI+) (Image Processing)

执行结果
 如何使用C++/CLI对图片做Grayscale Opening? (.NET) (C/C++) (C++/CLI) (GDI+) (Image Processing)

See Also
如何使用C++/CLI对图片做Grayscale Dilation?
如何使用C++/CLI对图片做Grayscale Erosion?
如何使用C++/CLI对图片做Grayscale Closing?

你可能感兴趣的:(process)