PDA

View Full Version : پاک کردن نویز یک تصویر - OCR - matrix ...



mehrdad1991h
یک شنبه 27 بهمن 1392, 10:55 صبح
سلام
خوب یه تصویر داریم توش خط و نقطه زیادی هست (همون نویز)
میخوام این نویز ها را پاک کنم
چه میکنیم ؟
در ضمن تصویر سیاه و سفید هست (مزیت ما که البته با توجه به کد من فرقی هم نداره)

کاری که من میکنم
میام تصویر را ماتریکس بندی میکنم
بعد هر خونه را چک میکنم ببینم چی توشه و نویز ها را پاک میکنیم
حالا بگیرید پاک هم شد بعد موقع سیو هنگ میکنه خطا میده نمیتونه سیو کنه
کدی هم که من استفاده میکنم این زیر گذاشتم (چک کنید)

حالا یه کاری میخوام بکنم که این نویز ها پاک بشه من چه کنم که این عملی بشه چیزی به ذهن شما نمیرسه ؟
تو این اینترنت هم ما هرچی گشتیم هیچی نیست یه فیلم فقط پیا کردیم که اونم کدهاش مشخص نبود چجوریه همین یه تصویر میداد و خروجی میگرفت کد مد نداشت که بشه چک کرد چیکار میکنه !

لطفا اگر کسی نمونه چیزی راه حلی کمیک هر چیزی هست لطفا دریق نکنه من تو همین یه تیکه اش موندم


public static Bitmap RemoveNoise(Bitmap original, int level, int radius)
{
int width = original.Width;
int height = original.Height;
Bitmap source = null;
source = original.PixelFormat != PixelFormat.Format8bppIndexed
?
Make(original)
: original;
Bitmap destination = GrayscaleImage(width, height);
BitmapData srcData = source.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
source.PixelFormat);
BitmapData dstData = destination.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly,
destination.PixelFormat);

int stride = srcData.Stride;
byte pxVal;
int matrixWidth = (radius * 2 + 1) * (radius * 2 + 1);
var pxM = new byte[matrixWidth];
int meanIndex = (matrixWidth - 1) / 2;
unsafe
{
var srcScan0 = (byte*)srcData.Scan0;
var dstScan0 = (byte*)dstData.Scan0;

for (int l = 0; l < level; l++)
{
for (int y = radius; y < height - radius; y++)
{
byte* srcRow = srcScan0 + (y * stride);
byte* dstRow = dstScan0 + (y * stride);
for (int x = radius; x < width - radius; x++)
{
pxVal = srcRow[x];
int mIndex = 0;
for (int k = y - radius; k < y + radius + 1; k++)
{
byte* srcRowMatrix = srcScan0 + (k * stride);
for (int j = x - radius; j < x + radius + 1; j++)
{
pxM[mIndex++] = srcRowMatrix[j];
}
}
Array.Sort(pxM);
dstRow[x] = pxM[meanIndex];
}
}
}
}

destination.UnlockBits(dstData);
source.UnlockBits(srcData);

if (source != original)
source.Dispose();

return destination;
}
public static Bitmap Make(Bitmap original)
{
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
for (int i = 0; i < original.Width; i++)
{
for (int j = 0; j < original.Height; j++)
{
Color originalColor = original.GetPixel(i, j);
int grayScale = (int)((originalColor.R * .3) + (originalColor.G * .59)
+ (originalColor.B * .11));
Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);
newBitmap.SetPixel(i, j, newColor);
}
}

return newBitmap;
}
public static Bitmap GrayscaleImage(int width, int height)
{
Bitmap image = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
SetGrays(image);
return image;
}
public static void SetGrays(Bitmap image)
{
ColorPalette cp = image.Palette;
for (int i = 0; i < 256; i++)
{
cp.Entries[i] = Color.FromArgb(i, i, i);
}
image.Palette = cp;
}

mehrdad1991h
یک شنبه 27 بهمن 1392, 12:47 عصر
اینجا کسی سر در میاره اصلا از این چیزا
برم کجا بپرسم !:(

plus
یک شنبه 27 بهمن 1392, 16:22 عصر
اگه مشکل شما اینه که موقع Save خطا میده موضوع ربطی به OCR و کدهای دیگه که نوشتین نداره...من توی کدهاتون بخشی که در مورد Save باشه ندیدم و متن خطا رو هم نگذاشتین چطور انتظار دارین پاسخی بگیرین؟

rahnema1
یک شنبه 27 بهمن 1392, 19:09 عصر
سلام
این برنامه یک تصویر را می گیره، فیلتر میانه 3*3 اجرا می کنه و سپس ذخیره می کنه

void Button1Click(object sender, EventArgs e)
{
Bitmap bm0=new Bitmap(@"c:\myimage1.bmp");
int width=bm0.Width,height=bm0.Height;
Bitmap bm1=new Bitmap(width,height,PixelFormat.Format32bppRgb);
Graphics.FromImage(bm1).DrawImage(bm0,0,0);
Bitmap bm2=new Bitmap(width,height,PixelFormat.Format32bppRgb);
Graphics.FromImage(bm2).DrawImage(bm1,0,0);
List<List<int>> winw=new List<List<int>>(){
new List<int>(){-1,-1},
new List<int>(){-1,0},
new List<int>(){-1,1},
new List<int>(){0,-1},
new List<int>(){0,0},
new List<int>(){0,1},
new List<int>(){1,-1},
new List<int>(){1,0},
new List<int>(){1,1}};
BitmapData srcData = bm1.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bm1.PixelFormat);
BitmapData dstData = bm2.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly,bm2.PixelFormat);
unsafe
{
UInt32 * pBits1 = (UInt32 *)srcData.Scan0.ToPointer();
UInt32 * pBits2 = (UInt32 *)dstData.Scan0.ToPointer();
for ( int row = 1; row < height-1; ++row )
{
for ( int col = 1; col < width-1; ++col )
{
*(pBits2 + row*width + col)=winw.Select(xx=>*(pBits1 +(( row+xx[0])*width + col+xx[1]))).OrderBy(yy=>yy).ElementAt(5);
}
}
}
bm1.UnlockBits(srcData);
bm2.UnlockBits(dstData);
bm2.Save(@"c:\myimage2.tif",ImageFormat.Tiff);
}

mehrdad1991h
دوشنبه 28 بهمن 1392, 09:12 صبح
اگه مشکل شما اینه که موقع Save خطا میده موضوع ربطی به OCR و کدهای دیگه که نوشتین نداره...من توی کدهاتون بخشی که در مورد Save باشه ندیدم و متن خطا رو هم نگذاشتین چطور انتظار دارین پاسخی بگیرین؟

این برای ذخیره کردن من استفاده میکنم

Bitmap bmp = new Bitmap(@"C:\Users\1.jpg");
Bitmap resulrt = RemoveNoise(bmp, 1, 1);
string save = @"C:\Users\1.1.jpg";

resulrt.Save(save, ImageFormat.Jpeg);
///یا این یکی
Image i = (Image)resulrt;
i.Save(save, ImageFormat.Jpeg);


این هم خطایی که میدهد :

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

خوب حالا مشکل کجاست ؟

rahnema1
دوشنبه 28 بهمن 1392, 09:54 صبح
این خطا هنگامی رخ میده که شما می خواهید به بخشی از حافظه دسترسی پیدا کنید که مربوط به تصویر مورد نظر نمیشه یعنی اندکس دهی در برنامه اشکال داره و احتمالا اندکس به خارج از داده های تصویر اشاره می کنه

mehrdad1991h
دوشنبه 28 بهمن 1392, 10:08 صبح
این خطا هنگامی رخ میده که شما می خواهید به بخشی از حافظه دسترسی پیدا کنید که مربوط به تصویر مورد نظر نمیشه یعنی اندکس دهی در برنامه اشکال داره و احتمالا اندکس به خارج از داده های تصویر اشاره می کنه

خوب با این تفسیر من فکر میکنم حتما کد من مشکل داره
ولی اخه این درسته دیگه یه حلقه داره کار را میکنه این که نمیتونه خطا داشته باشه دیگه که:گیج:

rahnema1
دوشنبه 28 بهمن 1392, 17:44 عصر
این یکی تقریبا مشابه کد شماست اگه اشکال داشت بگید

void MedianFilter(string SrcImagePath, string DstImagePath, int radius,int level)
{
int matrixWidth = (radius * 2 + 1) * (radius * 2 + 1);
Bitmap kernel = new Bitmap((radius * 2 + 1) , (radius * 2 + 1), PixelFormat.Format32bppRgb);
Graphics kerGr=Graphics.FromImage(kernel);
Rectangle kerRect = new Rectangle(0, 0, kernel.Width, kernel.Height);
Rectangle MovkerRect = new Rectangle(-radius, -radius, kernel.Width, kernel.Height);
int[] pxM = new int[matrixWidth];
int medianIndex = (matrixWidth - 1) / 2;
Bitmap bm1 =Image.FromHbitmap(new Bitmap(SrcImagePath).GetHbitmap());
int width=bm1.Width;
int height=bm1.Height;
Bitmap bm2=new Bitmap(width,height,PixelFormat.Format8bppIndexed) ;
ColorPalette pal = (new Bitmap(1, 1, PixelFormat.Format8bppIndexed)).Palette;
for (int i = 0; i < 256; i++) {
pal.Entries[i]=Color.FromArgb(i,i,i);
}
bm2.Palette=pal;
BitmapData kerData;
BitmapData srcData = bm2.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bm2.PixelFormat);
unsafe
{
byte * pBits1 = (byte *)srcData.Scan0.ToPointer();
for (int l = 0; l < level; l++)
{
for ( int row = radius; row < height- radius; ++row )
{
for ( int col = radius; col < width- radius; ++col )
{
MovkerRect.X=-radius+col;
MovkerRect.Y=-radius+row;
kerGr.DrawImage(bm1,kerRect, MovkerRect, GraphicsUnit.Pixel);
kerData=kernel.LockBits(kerRect, ImageLockMode.ReadOnly, kernel.PixelFormat);
System.Runtime.InteropServices.Marshal .Copy(kerData.Scan0, pxM, 0, matrixWidth);
kernel.UnlockBits(kerData);
*(pBits1 + row*width + col)=pxM .Select(xx=> BitConverter.GetBytes(xx)[0]) .OrderBy(yy=>yy) .ElementAt(medianIndex);
}
}
}
}
bm2.UnlockBits(srcData);
bm2.Save(DstImagePath,ImageFormat.Tiff);
}