मैं कुछ दिनचर्या, लिखा है एक 3x3 गिरी का उपयोग कर एक ग्रेस्केल छवि को पैना करनेFFT कनवल्शन - 3x3 गिरी
-1 -1 -1
-1 9 -1
-1 -1 -1
निम्नलिखित कोड गैर FFT (स्थानिक-डोमेन) घुमाव के मामले में अच्छी तरह से काम कर रहा है, लेकिन, एफएफटी-आधारित (आवृत्ति-डोमेन) संकल्प में काम नहीं कर रहा है।
आउटपुट छवि धुंधला लगती है।
मैं कई समस्याएं हैं:
(1) यह दिनचर्या वांछित परिणाम उत्पन्न करने में सक्षम नहीं किया जा रहा है। यह एप्लिकेशन को भी जमा करता है।
public static Bitmap ApplyWithPadding(Bitmap image, Bitmap mask)
{
if(image.PixelFormat == PixelFormat.Format8bppIndexed)
{
Bitmap imageClone = (Bitmap)image.Clone();
Bitmap maskClone = (Bitmap)mask.Clone();
/////////////////////////////////////////////////////////////////
Complex[,] cPaddedLena = ImageDataConverter.ToComplex(imageClone);
Complex[,] cPaddedMask = ImageDataConverter.ToComplex(maskClone);
Complex[,] cConvolved = Convolution.Convolve(cPaddedLena, cPaddedMask);
return ImageDataConverter.ToBitmap(cConvolved);
}
else
{
throw new Exception("not a grascale");
}
}
(2) यह दिनचर्या अच्छा परिणाम देता है। लेकिन, नरक के रूप में धीमी है।
public static Bitmap Apply(Bitmap sourceBitmap)
{
Sharpen filter = new Sharpen();
BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0,
sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height];
byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height];
Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length);
sourceBitmap.UnlockBits(sourceData);
double blue = 0.0;
double green = 0.0;
double red = 0.0;
int filterWidth = filter.FilterMatrix.GetLength(1);
int filterHeight = filter.FilterMatrix.GetLength(0);
int filterOffset = (filterWidth - 1)/2;
int calcOffset = 0;
int byteOffset = 0;
for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++)
{
for (int offsetX = filterOffset; offsetX <
sourceBitmap.Width - filterOffset; offsetX++)
{
blue = 0;
green = 0;
red = 0;
byteOffset = offsetY *
sourceData.Stride +
offsetX * 4;
for (int filterY = -filterOffset;
filterY <= filterOffset; filterY++)
{
for (int filterX = -filterOffset;
filterX <= filterOffset; filterX++)
{
calcOffset = byteOffset +
(filterX * 4) +
(filterY * sourceData.Stride);
blue += (double)(pixelBuffer[calcOffset]) *
filter.FilterMatrix[filterY + filterOffset,
filterX + filterOffset];
green += (double)(pixelBuffer[calcOffset + 1]) *
filter.FilterMatrix[filterY + filterOffset,
filterX + filterOffset];
red += (double)(pixelBuffer[calcOffset + 2]) *
filter.FilterMatrix[filterY + filterOffset,
filterX + filterOffset];
}
}
blue = filter.Factor * blue + filter.Bias;
green = filter.Factor * green + filter.Bias;
red = filter.Factor * red + filter.Bias;
if (blue > 255)
{ blue = 255; }
else if (blue < 0)
{ blue = 0; }
if (green > 255)
{ green = 255; }
else if (green < 0)
{ green = 0; }
if (red > 255)
{ red = 255; }
else if (red < 0)
{ red = 0; }
resultBuffer[byteOffset] = (byte)(blue);
resultBuffer[byteOffset + 1] = (byte)(green);
resultBuffer[byteOffset + 2] = (byte)(red);
resultBuffer[byteOffset + 3] = 255;
}
}
Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);
BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0,
resultBitmap.Width, resultBitmap.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length);
resultBitmap.UnlockBits(resultData);
return resultBitmap;
}
(3) निम्नलिखित मेरी जीयूआई कोड है। SharpenFilter.ApplyWithPadding()
अगर मैं एक मुखौटा के रूप में छवि का उपयोग करता हूं तो ठीक से काम करता है। लेकिन, अगर मैं, 3
x 3
कर्नेल का उपयोग करता हूं, तो काम नहीं करता है।
string path = @"E:\lena.png";
string path2 = @"E:\mask.png";
Bitmap _inputImage;
Bitmap _maskImage;
private void LoadImages_Click(object sender, EventArgs e)
{
_inputImage = Grayscale.ToGrayscale(Bitmap.FromFile(path) as Bitmap);
/*
_maskImage = Grayscale.ToGrayscale(Bitmap.FromFile(path2) as Bitmap);
*/
SharpenFilter filter = new SharpenFilter();
double[,] mask = new double[,] { { -1, -1, -1, },
{ -1, 9, -1, },
{ -1, -1, -1, }, };
_maskImage = ImageDataConverter.ToBitmap(mask);
inputImagePictureBox.Image = _inputImage;
maskPictureBox.Image = _maskImage;
}
Bitmap _paddedImage;
Bitmap _paddedMask;
private void padButton_Click(object sender, EventArgs e)
{
Bitmap lena = Grayscale.ToGrayscale(_inputImage);
Bitmap mask = Grayscale.ToGrayscale(_maskImage);
////Not working...
//int maxWidth = (int)Math.Max(lena.Width, mask.Width);
//int maxHeight = (int)Math.Max(lena.Height, mask.Height);
////This is working correctly in case if I use a png image as a mask.
int maxWidth = (int)Tools.ToNextPow2(Convert.ToUInt32(lena.Width + mask.Width));
int maxHeight = (int)Tools.ToNextPow2(Convert.ToUInt32(lena.Height + mask.Height));
_paddedImage = ImagePadder.Pad(lena, maxWidth, maxHeight);
_paddedMask = ImagePadder.Pad(mask, maxWidth, maxHeight);
paddedImagePictureBox.Image = _paddedImage;
paddedMaskPictureBox.Image = _paddedMask;
}
private void filterButton_Click(object sender, EventArgs e)
{
// Not working properly.
// Freezes the application.
Bitmap sharp = SharpenFilter.ApplyWithPadding(_paddedImage, _paddedMask);
////Works well. But, very slow.
//Bitmap sharp = SharpenFilter.Apply(_paddedImage);
filteredPictureBox.Image = sharp as Bitmap;
}
आउटपुट:
स्रोत कोड:
- यो आप पूरे समाधान को here in this link से डाउनलोड कर सकते हैं।
हाय:
आसान दृश्य तुलना के लिए, यहाँ मूल छवि फिर से है निर्दिष्ट किया कि 'Convolution.Convolve (x, y) 'क्या करता है? किसी भी मामले में चारों ओर अंतरिक्ष में कनवॉल्यूशन एक गुणा है। तो यदि आप जटिल रूप से शब्द को गुणा करके cPaddedLena और cPaddedMask के चार प्रकार के परिवर्तन को बदलते हैं (उन्हें चौकोर स्थान में समान आयाम होने के लिए गद्देदार होना चाहिए) और उलटा चौराहे ऑपरेशन को बदल देगा –