اشتراکها
You have a finite number of keystrokes left in your hands before you die
اشتراکها
روشهایی برای بهبود کیفیت کدها
مطالب
OpenCVSharp #15
تشخیص چهره به کمک OpenCV
OpenCV به کمک الگوریتمهای machine learning (در اینجا Haar feature-based cascade classifiers) و دادههای مرتبط با آنها، قادر است اشیاء پیچیدهای را در تصاویر پیدا کند. برای پیگیری مثال بحث جاری نیاز است کتابخانهی اصلی OpenCV را دریافت کنید؛ از این جهت که به فایلهای XML موجود در پوشهی opencv\sources\data\haarcascades آن نیاز داریم. در اینجا از دو فایل haarcascade_eye_tree_eyeglasses.xml و haarcascade_frontalface_alt.xml آن استفاده خواهیم کرد (این دوفایل جهت سهولت کار، به همراه مثال این بحث نیز ارائه شدهاند).
فایل haarcascade_frontalface_alt.xml اصطلاحا trained data مخصوص یافتن چهرهی انسان در تصاویر است و فایل haarcascade_eye_tree_eyeglasses.xml کمک میکند تا بتوان در چهرهی یافت شده، چشمان شخص را نیز با دقت بالایی تشخیص داد؛ چیزی همانند تصویر ذیل:
مراحل تشخیص چهره توسط OpenCVSharp
ابتدا همانند سایر مثالهای OpenCV، تصویر مدنظر را به کمک کلاس Mat بارگذاری میکنیم:
همچنین در اینجا جهت بالا رفتن سرعت کار و بهبود دقت تشخیص چهره، این تصویر اصلی به یک تصویر سیاه و سفید تبدیل شدهاست و سپس متد Cv2.EqualizeHist بر روی آن فراخوانی گشتهاست. این متد وضوح تصویر را جهت یافتن الگوها بهبود میبخشد.
سپس فایل xml یاد شدهی در ابتدای بحث را توسط کلاس CascadeClassifier بارگذاری میکنیم:
پس از بارگذاری فایلهای XML اطلاعات نحوهی تشخیص چهره و اعضای آن، با فراخوانی متد DetectMultiScale، کار تشخیص چهره و استخراج آن از grayImage انجام خواهد شد. در اینجا minSize، اندازهی حداقل چهرهی مدنظر است که قرار هست تشخیص داده شود. نواحی کوچکتر از این اندازه، به عنوان نویز در نظر گرفته خواهند شد و پردازش نمیشوند.
خروجی این متد، مستطیلها و نواحی یافت شدهی مرتبط با چهرههای موجود در تصویر هستند. اکنون میتوان حلقهای را تشکیل داد و این نواحی را برای مثال با مستطیلهای رنگی، متمایز کرد:
در اینجا علاوه بر رسم یک مستطیل، به دور ناحیهی تشخیص داده شده، نحوهی استخراج تصویر آن ناحیه را هم در سطر var detectedFaceImage مشاهده میکنید.
همچنین اگر علاقمند باشیم تا در این ناحیهی یافت شده، چشمان شخص را نیز استخراج کنیم، میتوان به نحو ذیل عمل کرد:
کدهای ابتدایی آن همانند توضیحات قبل است. تنها تفاوت آن، استفاده از nestedCascade بارگذاری شدهی در ابتدای بحث میباشد. این nestedCascade حاوی trained data استخراج چشمان اشخاص، از تصاویر است. پارامتر ورودی آنرا نیز تصویر سیاه و سفید ناحیهی چهرهی یافت شده، قرار دادهایم تا سرعت تشخیص چشمان شخص، افزایش یابد.
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید.
OpenCV به کمک الگوریتمهای machine learning (در اینجا Haar feature-based cascade classifiers) و دادههای مرتبط با آنها، قادر است اشیاء پیچیدهای را در تصاویر پیدا کند. برای پیگیری مثال بحث جاری نیاز است کتابخانهی اصلی OpenCV را دریافت کنید؛ از این جهت که به فایلهای XML موجود در پوشهی opencv\sources\data\haarcascades آن نیاز داریم. در اینجا از دو فایل haarcascade_eye_tree_eyeglasses.xml و haarcascade_frontalface_alt.xml آن استفاده خواهیم کرد (این دوفایل جهت سهولت کار، به همراه مثال این بحث نیز ارائه شدهاند).
فایل haarcascade_frontalface_alt.xml اصطلاحا trained data مخصوص یافتن چهرهی انسان در تصاویر است و فایل haarcascade_eye_tree_eyeglasses.xml کمک میکند تا بتوان در چهرهی یافت شده، چشمان شخص را نیز با دقت بالایی تشخیص داد؛ چیزی همانند تصویر ذیل:
مراحل تشخیص چهره توسط OpenCVSharp
ابتدا همانند سایر مثالهای OpenCV، تصویر مدنظر را به کمک کلاس Mat بارگذاری میکنیم:
var srcImage = new Mat(@"..\..\Images\Test.jpg"); Cv2.ImShow("Source", srcImage); Cv2.WaitKey(1); // do events var grayImage = new Mat(); Cv2.CvtColor(srcImage, grayImage, ColorConversion.BgrToGray); Cv2.EqualizeHist(grayImage, grayImage);
سپس فایل xml یاد شدهی در ابتدای بحث را توسط کلاس CascadeClassifier بارگذاری میکنیم:
var cascade = new CascadeClassifier(@"..\..\Data\haarcascade_frontalface_alt.xml"); var nestedCascade = new CascadeClassifier(@"..\..\Data\haarcascade_eye_tree_eyeglasses.xml"); var faces = cascade.DetectMultiScale( image: grayImage, scaleFactor: 1.1, minNeighbors: 2, flags: HaarDetectionType.Zero | HaarDetectionType.ScaleImage, minSize: new Size(30, 30) ); Console.WriteLine("Detected faces: {0}", faces.Length);
خروجی این متد، مستطیلها و نواحی یافت شدهی مرتبط با چهرههای موجود در تصویر هستند. اکنون میتوان حلقهای را تشکیل داد و این نواحی را برای مثال با مستطیلهای رنگی، متمایز کرد:
var rnd = new Random(); var count = 1; foreach (var faceRect in faces) { var detectedFaceImage = new Mat(srcImage, faceRect); Cv2.ImShow(string.Format("Face {0}", count), detectedFaceImage); Cv2.WaitKey(1); // do events var color = Scalar.FromRgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255)); Cv2.Rectangle(srcImage, faceRect, color, 3); count++; } Cv2.ImShow("Haar Detection", srcImage); Cv2.WaitKey(1); // do events
همچنین اگر علاقمند باشیم تا در این ناحیهی یافت شده، چشمان شخص را نیز استخراج کنیم، میتوان به نحو ذیل عمل کرد:
var rnd = new Random(); var count = 1; foreach (var faceRect in faces) { var detectedFaceImage = new Mat(srcImage, faceRect); Cv2.ImShow(string.Format("Face {0}", count), detectedFaceImage); Cv2.WaitKey(1); // do events var color = Scalar.FromRgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255)); Cv2.Rectangle(srcImage, faceRect, color, 3); var detectedFaceGrayImage = new Mat(); Cv2.CvtColor(detectedFaceImage, detectedFaceGrayImage, ColorConversion.BgrToGray); var nestedObjects = nestedCascade.DetectMultiScale( image: detectedFaceGrayImage, scaleFactor: 1.1, minNeighbors: 2, flags: HaarDetectionType.Zero | HaarDetectionType.ScaleImage, minSize: new Size(30, 30) ); Console.WriteLine("Nested Objects[{0}]: {1}", count, nestedObjects.Length); foreach (var nestedObject in nestedObjects) { var center = new Point { X = Cv.Round(nestedObject.X + nestedObject.Width * 0.5) + faceRect.Left, Y = Cv.Round(nestedObject.Y + nestedObject.Height * 0.5) + faceRect.Top }; var radius = Cv.Round((nestedObject.Width + nestedObject.Height) * 0.25); Cv2.Circle(srcImage, center, radius, color, thickness: 3); } count++; } Cv2.ImShow("Haar Detection", srcImage); Cv2.WaitKey(1); // do events
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید.
شیرپوینت 2013 تغییرات محسوسی در ظاهر خود و در واسط کاربریش اعمال کرده است . یکی از این تغییرات JS Link است که به کاربر امکان مدیریت روی Render کردن موجودیتهای روی صفحه مانند فیلدها ، آیتمها و وب پارتها را به کمک جاوااسکریپت میدهد. در این پست نحوه استفاده از این ویژگی جدید را بیان میکنم .
وارد سایت شده و یک لیست ایجاد کنید . (در اینجا از Custom List استفاده میکنیم .)
و ان را داده آمایی میکنیم . هدف این است که بر مبنای عدد موجود در لیست ، رنگ زمینه آن ایتم تغییر کند .
یک فایل جاوااسکریپت ایجاد کنید و کد زیر را در آن ذخیره کنید (از اینجا دانلود کنید) :
(function () { var itemCtx = {}; itemCtx.Templates = {}; itemCtx.Templates.Header = "<div><b title=\"اطلاعات فیلم ها\">Movie Data</b></div><ul>"; itemCtx.Templates.Item = MyOverrideTemplate; itemCtx.Templates.Footer = "</ul>"; itemCtx.BaseViewID = 1; itemCtx.ListTemplateType = 100; //For Generic List (More : http://msdn.microsoft.com/en-us/library/ms462947(v=office.12).aspx) SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx); })(); function GT(val , index) { // example of val : 60 % var temp = val.split(' ')[0]; var v = Number(temp); return v > index; } function LT(val, index) { var temp = val.split(' ')[0]; var v = Number(temp); return v < index; } function EQ(val, index) { var temp = val.split(' ')[0]; var v = Number(temp); return v == index; } function MyOverrideTemplate(ctx) { if (LT(ctx.CurrentItem.PopularityPercent ,25)) { return "<li title='خیلی کم بازدید' style='color:white;background-color: red;width: 300px;height: 24px;'>" + ctx.CurrentItem.Title + " – " + ctx.CurrentItem.PopularityPercent + "</li>"; } else if (LT(ctx.CurrentItem.PopularityPercent ,50)) { return "<li title='کم بازدید' style='color:maroon;background-color: #ffcc00;width: 300px;height: 24px;'>" + ctx.CurrentItem.Title + " – " + ctx.CurrentItem.PopularityPercent + "</li>"; } else if (LT(ctx.CurrentItem.PopularityPercent ,75)) { return "<li title='بازدید معمولی' style='color:#ffcc00;background-color: maroon;width: 300px;height: 24px;'>" + ctx.CurrentItem.Title + " – " + ctx.CurrentItem.PopularityPercent + "</li>"; } else if (LT(ctx.CurrentItem.PopularityPercent ,95)) { return "<li title='پر بازدید' style='color:yellow;background-color: blue;width: 300px;height: 24px;'>" + ctx.CurrentItem.Title + " – " + ctx.CurrentItem.PopularityPercent + "</li>"; } else if (EQ(ctx.CurrentItem.PopularityPercent, 100)) { return "<li title='بالاترین بازدید' style='color:black;background-color: green;width: 300px;height: 24px;'>" + ctx.CurrentItem.Title + " – " + ctx.CurrentItem.PopularityPercent + "</li>"; } else { return "<li title='نامعلوم' style='color:navy;background-color: yellow;width: 300px;height: 24px;'>" + ctx.CurrentItem.Title + " – " + ctx.CurrentItem.PopularityPercent + "</li>"; } }
حال وارد Site Setting شده و وارد Master Pages شوید
فایل جاوااسکریپت فوق را از قسمت ریبون و تب Document آپلود کنید و منتظر بمانید تا پس از بارگذاری پنجره ویژگیهای فایل نمایش داده شود
هنگلام پر کردن فیلدها به این نکات دقت کنید :
در قسمت Content Type گزینه جدیدی که در این نسخه از شیرپوینت اضافه شده یعنی JavaScript Display Template را انتخاب کنید
در قسمت Target Control Type یکی از سه گزینه view یا Form ویا Field باید انتخاب شوند که در اینجا View را انتخاب میکنیم
standalone را روی override تنظیم میکنیم . همچنین گزینه Target Scope را که مسیر اعمال فایل است به رووت تنظیم میکنیم
در نهایت شناسه List template را به توجه به لیست مورد نظر که در اینجا Custome list است مقدار دهی میکنیم . (بیشتر )
سپس اطلاعات را ذخیره میکنیم .
برای آزمایش این تغییرات بک صفحه میسازیم و وب پارت لیست مورد نظر را به آن اضافه میکنیم
سپس وارد تنظیمات وب پارت شده و وارد قسمت Miscellaneous میشویم
در قسمت JS Link مسیر فایل خود را به صور نسبی وارد کنید
~site/_catalogs/masterpage/MyJsLinkSample.js
و نتیجه نهایی :
در صورت بروز Exception در فایل جاوااسکریپت ، خطا به صورت زیر نمایش داده خواهد شد :
اشتراکها
دوره کامل Typescript
نظرات مطالب
آموزش TypeScript #1
بله امکان پذیر است. اما با توجه به این نکته که فلسفه وجودی TypeScript این است که در پروژه هایی با مقیاس پزرگ برای سازمان دهی کدهای سمت کلاینت مورد استفاده قرار گیرند و یکی از روشهای سازمان دهی کدها این است که کدهای TypeScript در فایل هایی جداگانه با پسوند ts ذخیره شده تا کامپایل و تبدیل به کد JavaScript شوند(مهمترین مزیت این روش این است که از نوشتن کدهای تکراری جلوگیری میشود). اما در صورتی که مایل به نوشتن کد به صورت Embed در تگ Script هستید باید از پروژههای متن بازی همچون TypeScript Compile یا ts-htaccess استفاده کنید.
ارسال پیامهای تبلیغاتی از طریق نرم افزارهایی مثل Viber , Telegram این روزها بازار داغی دارند. این نرم افزارها به همراه خود Api هایی را نیز جهت توسعه دهندگان ارائه میدهند. Telagram هم که به یکی از محبوبترین نرم افزارها در ایران تبدیل شدهاست. اگر به مستندات Telegram مراجعه کنید، میتوانید نحوهی استفاده را مشاهده کنید. ولی روشهای دیگری هم هستند که بسیار سادهتر هستند.
اگر به سایت notificatio.me مراجعه کنید، در این زمینه Api ایی را ارائه میدهد که به راحتی میتوانید از آن برای ارسال پیام استفاده کنید. البته تا ارسال 100 پیام آن رایگان هست.
ابتدا یک پروژهی از نوع Windows و یا console را ایجاد کنید.
سپس در خط فرمان package manager console دستور زیر را کپی کنید:
Install-Package Notificatio.TelegramClient
پس از نصب شدن بستهی Nuget، یک دکمه روی فرم قرار دهید و در رویداد OnClick آن دستورات زیر را تایپ کنید:
var api = NotificatioApi.Initialize(" Your Hash_Key"); api.SendMessage("Phone Number", "this is a test Message");
در آخر برنامه را اجرا کنید و بر روی دکمه، کلیک کنید. پس از اتمام کار ارسال، برای مشاهدهی تعداد پیامهای ارسال شده و یا آمار ماهانه، در سایت فوق میتوانید به Dashboard آن مراجعه کنید و تعداد و آمار پیامهای ارسالی را ببینید.
البته با استفاده از jQuery هم میتوانید کار ارسال پیام را انجام دهید:
$.ajax({ url: "http://www.api.notificatio.me/v1/user/message", type: "POST", dataType: "json", crossDomaint: true, data: { phoneNumber: "your_phone_number", apiHash: "your_api_hash", message: "your_message" }, cache: false, success: function() { // Your code to handle success message sent }, error: function(error) { // Your code to handle error } });