0

Affectivaの github リポジトリからcsharp-sample-appsをたどることができました。Web カメラを使用してデモを実行しましたが、処理とパフォーマンスは素晴らしかったです。ファイル システム内の画像に対して実行しようとすると、PhotoDetector から同じ処理速度が得られません。ヘルプや改善をいただければ幸いです。

namespace Logical.EmocaoFace
{
    public class AnaliseEmocao : Affdex.ImageListener, Affdex.ProcessStatusListener
    {
        private Bitmap img { get; set; }
        private Dictionary<int, Affdex.Face> faces { get; set; }
        private Affdex.Detector detector { get; set; }
        private ReaderWriterLock rwLock { get; set; }

        public void processaEmocaoImagem()
        {

            for (int i = 0; i < resultado.count; i++){

                RetornaEmocaoFace();

                if (faceAffdex != null)
                {

                }
            }
        }


        public void RetornaEmocaoFace(string caminhoImagem)
        {
            Affdex.Detector detector = new Affdex.PhotoDetector(1, Affdex.FaceDetectorMode.LARGE_FACES);
            detector.setImageListener(this);
            detector.setProcessStatusListener(this);

            if (detector != null)
            {
                //ProcessVideo videoForm = new ProcessVideo(detector);
                detector.setClassifierPath(@"D:\Desenvolvimento\Componentes\Afectiva\data");
                detector.setDetectAllEmotions(true);
                detector.setDetectAllExpressions(false);
                detector.setDetectAllEmojis(false);
                detector.setDetectAllAppearances(false);
                detector.start();

                ((Affdex.PhotoDetector)detector).process(LoadFrameFromFile(caminhoImagem));

                detector.stop();
            }
        }

        static Affdex.Frame LoadFrameFromFile(string fileName)
        {
            Bitmap bitmap = new Bitmap(fileName);

            // Lock the bitmap's bits.
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap. 
            int numBytes = bitmap.Width * bitmap.Height * 3;
            byte[] rgbValues = new byte[numBytes];

            int data_x = 0;
            int ptr_x = 0;
            int row_bytes = bitmap.Width * 3;

            // The bitmap requires bitmap data to be byte aligned.
            // http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size

            for (int y = 0; y < bitmap.Height; y++)
            {
                Marshal.Copy(ptr + ptr_x, rgbValues, data_x, row_bytes);//(pixels, data_x, ptr + ptr_x, row_bytes);
                data_x += row_bytes;
                ptr_x += bmpData.Stride;
            }

            bitmap.UnlockBits(bmpData);

            //Affdex.Frame retorno = new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);

            //bitmap.Dispose();

            //return retorno;

           return new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
        }

        public void onImageCapture(Affdex.Frame frame)
        {
            frame.Dispose();

        }

        public void onImageResults(Dictionary<int, Affdex.Face> faces, Affdex.Frame frame)
        {
            byte[] pixels = frame.getBGRByteArray();
            this.img = new Bitmap(frame.getWidth(), frame.getHeight(), PixelFormat.Format24bppRgb);
            var bounds = new Rectangle(0, 0, frame.getWidth(), frame.getHeight());
            BitmapData bmpData = img.LockBits(bounds, ImageLockMode.WriteOnly, img.PixelFormat);
            IntPtr ptr = bmpData.Scan0;

            int data_x = 0;
            int ptr_x = 0;
            int row_bytes = frame.getWidth() * 3;

            // The bitmap requires bitmap data to be byte aligned.
            // http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size

            for (int y = 0; y < frame.getHeight(); y++)
            {
                Marshal.Copy(pixels, data_x, ptr + ptr_x, row_bytes);
                data_x += row_bytes;
                ptr_x += bmpData.Stride;
            }
            img.UnlockBits(bmpData);

            this.faces = faces;

            frame.Dispose();
        }

        public void onProcessingException(Affdex.AffdexException A_0)
        {
            throw new NotImplementedException("Encountered an exception while processing " + A_0.ToString());
        }

        public void onProcessingFinished()
        {
            string idArquivo = CodEspaco + "," + System.Guid.NewGuid().ToString();

            for(int i = 0; i  < faces.Count; i++)
            {
            }
        }



    }

    public static class GraphicsExtensions
    {
        public static void DrawCircle(this Graphics g, Pen pen,
                                      float centerX, float centerY, float radius)
        {
            g.DrawEllipse(pen, centerX - radius, centerY - radius,
                          radius + radius, radius + radius);
        }
    }
}
4

1 に答える 1

0

私自身の質問に対する答えを見つけました:

この場合、PhotoDetectorの使用は理想的ではありません。これは、後続のフレーム呼び出しで Face Detector 構成を使用するとコストがかかるためです。

パフォーマンスを向上させる最善の方法は、FrameDetectorクラスのインスタンスを使用することです。

これはanalyze-frames の入門ガイドです。

于 2016-10-03T17:30:25.337 に答える