PDA

View Full Version : استفاده از اشاره گر ها در پردازش تصوير



unrealelec
سه شنبه 19 فروردین 1393, 22:38 عصر
با سلام خدمت دوستان
من با استفاده از كدهاي زير يك عكس رنگي رو تبديل به سياه و سفيد مي كنم

string pic = openFileDialog1.FileName;
pictureBox1.Image = Image.FromFile(pic);
Bitmap BMP = new Bitmap(pictureBox1.Image);
Color col;
int marz = 128;
for (int i = 0; i < Int32.Parse(BMP.Width.ToString()); i++)
{
for (int j = 0; j < Int32.Parse(BMP.Height.ToString()); j++)
{
col = BMP.GetPixel(i, j);
if (col.R > marz)
{
BMP.SetPixel(i, j, Color.FromArgb(255, 255, 255));
}
else
{
BMP.SetPixel(i, j, Color.FromArgb(0, 0, 0));
}
}
}
pictureBox1.Image = BMP;
ولي مشكلي كه هست اينه كه اين الگوريتم خيلي كنده و براي تصاوير با پيكسل هاي زياد ، چند ثانيه طول مي كشه ، توي تاپيكي خوندم كه از اشاره گر ها براي افزايش سرعت پردازش استفاده مي كنن ، مي خواستم ببينم دوستان مي تونن اطلاعاتي تو اين زمينه بدن كه مثلا همين الگوريتم بالا بايد به چه فرمي باشه؟

Mousavmousab
سه شنبه 19 فروردین 1393, 23:19 عصر
الگوریتم که تغییر نمیکنه
باید از pointer استفاده کنی
برای استفاده از اشاره باید به کامپایلر بگی که کد های Unsafe می خوای بنویسی و شما را تایید کنه ، آخه شما در حالت عادی توی سی شارپ Safe کد می زنی.
یه CheckBox را باید tick بزنی
به این آدرس برو :
برای استفاده از pointer باید روی Solution Explorerراست کلیک کنی و properties
توی سربرگ Build باید گزینه Allow Unsafe Code را تیک بزنی

بعد تابع ها را به این صورت بنویس
من یه اشاره گر ساده در سی شارپ می نویسم بقیه با خودت
یه label و button را روی فرم قرار بده

117772

امیدوارم به دردت بخوره
موفق باشی

مهرداد صفا
سه شنبه 19 فروردین 1393, 23:32 عصر
سلام.
با استفاده از روشی که در این تاپیک (http://barnamenevis.org/showthread.php?414492-%D8%AA%D8%A8%D8%AF%DB%8C%D9%84-%D9%85%D9%82%D8%A7%D8%AF%DB%8C%D8%B1-RGB-%D8%A8%D9%87-%D9%BE%DB%8C%DA%A9%D8%B3%D9%84-%DB%8C%D8%A7-%DB%8C%DA%A9-%D8%B9%DA%A9%D8%B3) گفته شده داده های Bitmap را در یک آرایه بخوانید و بعد از انجام عملیات مورد نظر روی داده ها، به همان روش مججدا داده ها را در Bitmap بازنویسی کنید.

unrealelec
چهارشنبه 20 فروردین 1393, 13:52 عصر
سلام.
با استفاده از روشی که در این تاپیک (http://barnamenevis.org/showthread.php?414492-%D8%AA%D8%A8%D8%AF%DB%8C%D9%84-%D9%85%D9%82%D8%A7%D8%AF%DB%8C%D8%B1-RGB-%D8%A8%D9%87-%D9%BE%DB%8C%DA%A9%D8%B3%D9%84-%DB%8C%D8%A7-%DB%8C%DA%A9-%D8%B9%DA%A9%D8%B3) گفته شده داده های Bitmap را در یک آرایه بخوانید و بعد از انجام عملیات مورد نظر روی داده ها، به همان روش مججدا داده ها را در Bitmap بازنویسی کنید.
با تشكر از راهنمايي مفيدتون ، كد رو به شكل زير اصلاح كردم
در فرم 1 تصوير رو در كلاس زير ذخيره مي كنم

namespace WindowsFormsApplication1{
class picmatris
{
private static Bitmap TSH;


public static Bitmap TSHT
{
set
{
TSH = value;
}
get
{
return TSH;
}
}
}
}
بعد با زدن يك دكمه در فرم 1 ، فرم 2 كه به فرم پايين هست را فراخواني مي كنيم

namespace WindowsFormsApplication1{
public partial class Form2 : Form
{
[System.Runtime.InteropServices.DllImport("kernel32 ")]
static extern void RtlMoveMemory(IntPtr destination, ref byte source, int count);
public Form2()
{
InitializeComponent();
Bitmap BMP = picmatris.TSHT;
this.Size = BMP.Size;
int marz = 128;
Bitmap FormBitmap = new Bitmap(this.Width, this.Height);
byte[, ,] pixels = new byte[ this.Height,this.Width, 3];
for (int i = 0; i < this.Width; i++)
{
for (int j = 0; j < this.Height; j++)
{
if (BMP.GetPixel(i, j).R > marz)
{
pixels[j, i, 0] = 255;//b
pixels[j, i, 1] = 255;//r
pixels[j, i, 2] = 255;//g
}
}
}


BitmapData data = FormBitmap.LockBits(new Rectangle(0, 0, this.Width, this.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
RtlMoveMemory(data.Scan0, ref pixels[0, 0, 0], pixels.Length);
FormBitmap.UnlockBits(data);
this.BackgroundImage = FormBitmap;
}


}
}
الان سرعت خيلي بهتر شد ولي اگر مثلا قبلي 8 ثانيه طول مي كشيد كد جديد 2 ثانيه زمان مي بره آيا راهي هست تا زمان رو كمتر كنم؟

rahnema1
چهارشنبه 20 فروردین 1393, 21:37 عصر
فکر کنم اینجور سرعت بهتر بشه

byte marz=128;
Bitmap BMP =Image.FromHbitmap(new Bitmap(@"myfile.jpg").GetHbitmap());
BitmapData bmpData=BMP.LockBits(new Rectangle(0,0,BMP.Width,BMP.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
UInt32 * pBits1 = (UInt32 *)bmpData.Scan0.ToPointer();
for (UInt32 * i = pBits1; i < pBits1+BMP.Height*BMP.Width; i++)
*(i)=((((*(i))<<8)>>24) >marz? 0xFFFFFFFF:0);
}
BMP.UnlockBits(bmpData);
this.BackgroundImage = BMP;

unrealelec
چهارشنبه 20 فروردین 1393, 23:55 عصر
فکر کنم اینجور سرعت بهتر بشه

ممنون بخاطر كمكتون . كدهاي شما رو چك كردم كه سريعتر از كدهايي بود كه خودم بالا نوشتم ولي وقتي اندازه تصوير مثلا 3000*4000باشه زمان كدهاي شما چيزي حدود 20 ثانيه هست و كدهاي من كمي بيشتر در حالي كه من تو سايت codeproject يك demo ديدم كه همين كار رو براي تصويري به همين اندازه زير يك ثانيه انجام داده بود . مي خواستم ببينم دوستان پيشنهادي تو اين زمينه ندارن؟
(يك نكته براي دوستاني كه احتمالا بعدا اين تاپيك رو بخونن بايد بگم ، اون هم اينه كه تو كدهايي كه من نوشتم وقتي اندازه تصوير از يك حدي بزرگتر مي شه بايد اين خط حذف بشه:
;this.Size = BMP.Size
و Heightو Width هم از روي اندازه BMP.Heightو BMP.Width مقدار دهي بشن نه از روي this.Height و this.Width اگر اينكار انجام نشه تغييرات روي تمام پيكسل ها اعمال نميشه)

مهرداد صفا
پنج شنبه 21 فروردین 1393, 00:52 صبح
سلام.
در این تاپیک (http://barnamenevis.org/showthread.php?355051-%DA%A9%D9%85%DA%A9-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-%D8%AA%D8%B9%D9%82%DB%8C%D8%B1-%D8%B1%D9%86%DA%AF-image-%D8%A8%D9%87-%D8%B3%DB%8C%D8%A7%D9%87-%D9%88-%D8%B3%D9%81%DB%8C%D8%AF) سریعترین راه برای این کار (استفاده از Matrix) گفته شده.
در ضمن لطفا لینک مقاله ای که در CodeProject دیدید رو هم محبت کنید.

unrealelec
پنج شنبه 21 فروردین 1393, 09:09 صبح
سلام.
در این تاپیک (http://barnamenevis.org/showthread.php?355051-%DA%A9%D9%85%DA%A9-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-%D8%AA%D8%B9%D9%82%DB%8C%D8%B1-%D8%B1%D9%86%DA%AF-image-%D8%A8%D9%87-%D8%B3%DB%8C%D8%A7%D9%87-%D9%88-%D8%B3%D9%81%DB%8C%D8%AF) سریعترین راه برای این کار (استفاده از Matrix) گفته شده.
در ضمن لطفا لینک مقاله ای که در CodeProject دیدید رو هم محبت کنید.
سلام
، http://www.codeproject.com/Articles/9727/Image-Processing-Lab-in-C
تو اين لينك ، سورس برنامه با يك توضيح مختصر نوشته شده ، برنامه رو با استفاده ار كتابخانه AForge.NET (http://code.google.com/p/aforge/) و كامپوننت ها مخصوص اون نوشته ، و البته خيلي حرفه اي. اون قسمتي هم كه من از اون صحبت كردم فيلتر Threshold هستش ، راستش هدف من تو اين تاپيك اختراع از اول چرخ نبود بلكه چون مي خواستم به سخت افزار نزديك بشم مي خواستم بتونم خودم الگوريتم Threshold رو پياده سازي كنم ولي خوب اولا مبتدي هستم و ثانيا فهميدن كدهاي يك برنامه كار سختيه . اگر شما مطلب جديدي متوجه شدين لطف مي كنين اگر تو اين تاپيك مبحث رو ادامه بديم

rahnema1
پنج شنبه 21 فروردین 1393, 20:51 عصر
سلام
، http://www.codeproject.com/Articles/9727/Image-Processing-Lab-in-C
تو اين لينك ، سورس برنامه با يك توضيح مختصر نوشته شده ، برنامه رو با استفاده ار كتابخانه AForge.NET (http://code.google.com/p/aforge/) و كامپوننت ها مخصوص اون نوشته ، و البته خيلي حرفه اي. اون قسمتي هم كه من از اون صحبت كردم فيلتر Threshold هستش ، راستش هدف من تو اين تاپيك اختراع از اول چرخ نبود بلكه چون مي خواستم به سخت افزار نزديك بشم مي خواستم بتونم خودم الگوريتم Threshold رو پياده سازي كنم ولي خوب اولا مبتدي هستم و ثانيا فهميدن كدهاي يك برنامه كار سختيه . اگر شما مطلب جديدي متوجه شدين لطف مي كنين اگر تو اين تاپيك مبحث رو ادامه بديم

این کتابخونه Aforge از اشاره گر ها استفاده می کنه و فکر نکنم سرعت بالایی داشته باشه
اگه تصویر شما سیاه و سفید باشه این کد سرعت بیشتری داره البته باید به WindowsBase و PresentationCore و System.Xaml رفرنس بدید


using System.Windows.Media;
using System.Windows.Media.Imaging;
//...
byte marz=128;
System.IO.Stream imageStreamSource = new System.IO.MemoryStream();
GifBitmapEncoder encoder = new GifBitmapEncoder();
string filename=@"myfile.jpg";
encoder.Frames.Add(BitmapFrame.Create(new FormatConvertedBitmap(new BitmapImage(new Uri(filename)), PixelFormats.Gray8,BitmapPalettes.Gray256, 0)));
encoder.Save(imageStreamSource);
ColorPalette pal = new Bitmap(1 ,1, System.Drawing.Imaging. PixelFormat.Format8bppIndexed ).Palette;
Enumerable.Range(0,256).Select(c=>pal.Entries[c]=(c>marz? System.Drawing.Color.White: System.Drawing.Color.Black)).ToArray();
Bitmap BMP = new Bitmap(imageStreamSource);
BMP.Palette=pal;
pictureBox1.Image=BMP;