على الرغم من كل المسرات التي تقدمها الإنترنت ، إلا أن لها العديد من العيوب ، وأحد أفظعها هو تضليل الناس. Clickbait ، تحرير الصور ، أخبار كاذبة - كل هذه الأدوات تستخدم بنشاط لخداع المستخدمين العاديين على الشبكة العالمية ، ولكن في السنوات الأخيرة اكتسبت أداة جديدة يحتمل أن تكون خطرة معروفة باسم DeepFake زخما.
كنت مهتمًا بهذه التقنية مؤخرًا. لأول مرة ، تعلمت ذلك من تقرير أحد المتحدثين في "مؤتمر منظمة العفو الدولية 2018". تم عرض شريط فيديو هناك ، حيث قامت الخوارزمية بإنشاء مقطع فيديو من خلال تسجيل صوتي بواسطة نداء باراك أوباما من خلال التسجيل الصوتي.
رابط إلى مجموعة مختارة من مقاطع الفيديو التي تم إنشاؤها باستخدام هذه التكنولوجيا . ألهمتني النتائج بشكل كبير ، وقررت فهم هذه التقنية بشكل أفضل من أجل معارضتها في المستقبل. لهذا ، قررت أن أكتب DeepFake في C #. نتيجة لذلك ، حصلت على هذه النتيجة.

هل لديك قراءة لطيفة!
المبادئ العامةكانت نقطة الانطلاق هي
هذا المشروع. من ذلك ، تعلمت بالضبط كيف يعمل استبدال الوجه في الفيديو.
- قم بتحميل صورة نلتقي بها
- استخراج الوجه
- إنشاء قناع 3D
- ينقسم الفيديو إلى إطارات
- يتم احتساب مساحة توطين الوجه في الإطار
- يتم احتساب زاوية وتعبير الوجه
- نقل التناوب وتعبيرات الوجه إلى نموذج ثلاثي الأبعاد
- أداء
- استبدال شخص حقيقي على الإطار بنتيجة العرض
فيديو يوضح عمل
مشروع FaceSwap :
قررت تقسيم العمل إلى 3 أجزاء:
أولاً) استبدال وجه في صورة مع وجه من صورة أخرى ، دون استخدام قناع ثلاثي الأبعاد
2) الانتهاء من استبدال باستخدام قناع 3D
3) معالجة الفيديو
يمكن أن يتحلل استبدال الوجه في الصورة إلى النقاط التالية:
- قم بتحميل صورة نلتقي بها
- قم بتحميل الصورة التي سنعرض عليها الوجه
- استخراج الوجه
- تحجيم الوجه المأخوذ من الصورة 2 إلى نسبة العرض إلى الارتفاع في الصورة 1
- استبدال الوجه في الصورة 1 بالوجه في الصورة 2
تضمين صورة واحدة في آخرأول شيء بدأت به هو دمج صورة في صورة أخرى. يتم استخدام البرنامج النصي
zad1.py لشرح التضمين في المشروع الأصلي.
نتيجة لذلك ، يتم إنشاء ملف "eyeHandBlend.jpg" ، حيث يتم تضمين العين في اليد.

تتكون هذه الخوارزمية من جزأين ، الأول ينقل اللون من المنطقة ذات الوجه في الصورة الأصلية إلى الوجه الذي يجب إدراجه. الثاني يجعل حواف الصورة ذات الوجه المطلوب شفافة ، مما يقلل الشفافية مع اقترابها من مركز الصورة.
لقد نقلت بالكامل الجزء الأول من المشروع الأصلي.
رمز بايثونdef colorTransfer(src, dst, mask): transferredDst = np.copy(dst)
الكود المنقول إلى C # static public Bitmap NewColor(Bitmap src, Bitmap ins, Rectangle r) { List<Vector> srV = new List<Vector>(); List<Vector> inV = new List<Vector>(); ; for (int i = rX; i < rX + r.Width-2; i+=3) { for (int j = rY; j < rY + r.Height-3; j+=4) { Color color = src.GetPixel(i, j); Color color2 = ins.GetPixel(i, j); srV.Add(new double[] { color.R, color.G, color.B }.ToVector()); inV.Add(new double[] { color2.R, color2.G, color2.B }.ToVector()); } } Vector meanSrc = Vector.Mean(srV.ToArray()) / 255; Vector meanInk = Vector.Mean(inV.ToArray()) / 255; Tensor tensor = ImgConverter.BmpToTensor (ins.Clone(r, PixelFormat.Format32bppArgb)); tensor = tensor.DivD(meanInk); tensor = tensor.PlusD(meanSrc); tensor = tensor.TransformTensor(x => { if (x < 0) x = 0; if (x > 1) x = 1; return x; }); return ImgConverter.TensorToBitmap(tensor); }
لجعل الحواف أكثر شفافية من الجزء المركزي من الصورة ، لحساب قناة ألفا ، تم تقديم وظيفة أساس شعاعي من النموذج التالي:
k=190n=3r=( fraci−Cw1.2 cdotW)2+( fracj−ChH)2 alpha=255 cdotexp(−k cdotrn)تم اختيار k و n بشكل تجريبي.
مؤشر i - بكسل على طول المحور OX
مؤشر ي بكسل على طول المحور OY
Cw - المكون العاشر لمركز الصورة
Chدولا - مكون y من مركز الصورة
نتيجة لذلك ، حصلت على النتيجة التالية:
البحث عن الوجهللبحث عن الوجوه في الصورة ، هناك العديد من الخوارزميات:
- فيولا جونز خوارزمية (هار كاسكيدز)
- خنزير + SVM
- R-CNN
- ص ص سريعة
- أسرع ص cnn
- يولو
في البداية ، تم استخدام خوارزمية فيولا جونز ، ولكن اتضح أنها ليست دقيقة بما فيه الكفاية ، لأنه الوجوه المميزة ليست بالضبط. لم تتزامن منطقة التحديد الخاصة بشخص واحد مع منطقة التحديد الخاصة بالشخص الثاني ، بسبب حدوث الاستبدال بالعيوب ، ويرد أدناه مثال على اختيار الوجوه باستخدام هذه الخوارزمية. يمكن إزاحة الوجوه ، أي في صورة واحدة تلتقط كلتا الأذنين ، من جهة أخرى. تؤثر هذه العيوب على النتيجة النهائية بشكل سيء إلى حد ما (في الصورة ، أثناء العمل مع DLib ، لم تجد المكتبة السابقة دائمًا الوجه ، ولكن للأسف لم يتم حفظ لقطات الشاشة).

بعد ذلك ، قررت استخدام المعالم من مكتبة دليب. وجدت
DlibDotNet ، وهو مكتوب على .Net Core. للاستخدام في .Net Framework ، تم إنشاء مشروع وسيط على .Net Standard 2.0 مع الوظائف الرئيسية والبحث عن الوجه وتسليط الضوء على المعالم.
رمز C # public int[] Face(byte[] bts, int row, int col, int st) { var img = Dlib.LoadImageData<RgbPixel> (ImagePixelFormat.Bgr, bts, (uint)row, (uint)col, (uint)st ); var face = faceDetector.Operator(img)[0]; int[] rect = { face.Left, face.Top, (int)face.Width, (int)face.Height}; return rect; } public List<int[]> FacePoints(byte[] bts, int row, int col, int st) { List<int[]> points = new List<int[]>(); var img = Dlib.LoadImageData<RgbPixel> (ImagePixelFormat.Bgr, bts, (uint)row, (uint)col, (uint)st); var face = faceDetector.Operator(img)[0]; var shape = shapePredictor.Detect(img, face); for (var i = 0; i < shape.Parts; i++) { var point = shape.GetPart((uint)i); points.Add(new int[] { point.X, point.Y }); } return points; }
ثم كتب مكتبة على .Net Framework 4.6.1 ، حيث قام بتنفيذ كل المنطق.
مثال على الحصول على Langmarks:

يمكن تمييز الشخص بشكل أكثر دقة من خلال إيجاد النقاط الموجودة في أقصى اليسار واليمين والعليا والسفلية وإنشاء إطارات عليها.

ثم تم قطع الوجه من الصورة في الركن الأيمن السفلي وأدخل ، باستخدام الخوارزمية الموضحة أعلاه ، في الصورة: "Caballero de la mano en el pecho".
تم الحصول على النتيجة التالية.

في المقالة التالية ، أخطط للنظر في إنشاء قناع ثلاثي الأبعاد من صورة.