(原創) 如何使用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
  5using namespace System::Drawing;
  6using namespace System::Drawing::Imaging;
  7
  8typedef std::pair<intint> MyPoint;
  9typedef std::vector<MyPoint> MyPointVec;
 10typedef int GrayLevel;
 11
 12// Make kernel by radius
 13MyPointVec makeKernel(const int&);
 14// Process opening
 15Bitmap^ opening(Bitmap^const MyPointVec%);
 16// Process dilation 
 17Bitmap^ dilation(Bitmap^const MyPointVec%); 
 18// Process erosion
 19Bitmap^ erosion(Bitmap^const MyPointVec%); 
 20// Get max gray level by kernel
 21GrayLevel getMaxByKernel(Bitmap^const MyPointVec%const MyPoint%);
 22// Get max gray level by kernel
 23GrayLevel getMinByKernel(Bitmap^const MyPointVec%const MyPoint%);
 24// Get gray level from Color object
 25GrayLevel getGrayLevelFromColor(Color^);
 26
 27int 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
 42MyPointVec 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
 90Bitmap^ opening(Bitmap^ image, const MyPointVec% kernel) {
 91  Bitmap^ newImage = dilation(erosion(image, kernel), kernel);
 92
 93  return newImage;
 94}

 95
 96// Process dilation 
 97Bitmap^ 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 
113Bitmap^ 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
130GrayLevel 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
154GrayLevel 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
179GrayLevel getGrayLevelFromColor(Color^ color) {
180  return (color->+ color->+ color->B) /3;
181}

原图

执行结果


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

posted on 2006-11-22 01:48  真 OO无双  阅读(1584)  评论(0编辑  收藏  举报

导航