Как обнаружить пользовательский объект с помощью EmguCV - PullRequest
0 голосов
/ 23 января 2020

Я работаю над кодом обнаружения объектов. Итак, я провел тренинг и получил файлы .pb и graph.pbtxt от tenorflow. Следующим, что я сделал, был код python, который выполняет обнаружение моего объекта на основе этих двух файлов, используя opencv для Python. Вот мой python скрипт, который хорошо работает:

import cv2 as cv

cvNet = cv.dnn.readNetFromTensorflow('frozen_inference_graph.pb', 'graph.pbtxt')

img = cv.imread('75.png')
rows = img.shape[0]
cols = img.shape[1]
cvNet.setInput(cv.dnn.blobFromImage(img, size=(300, 300), swapRB=True, crop=False))
cvOut = cvNet.forward()
print(rows)
print(cols)

for detection in cvOut[0,0,:,:]:
    print(type(cvOut[0,0,:,:]))
    score = float(detection[2])
    if score > 0.1:
        left = detection[3] * cols
        top = detection[4] * rows
        right = detection[5] * cols
        bottom = detection[6] * rows
        cv.rectangle(img, (int(left), int(top)), (int(right), int(bottom)), (0, 0, 255), thickness=2)
        print('true')
    print(score)

cv.imshow('img', cv.resize(img, None, fx=0.3, fy=0.3))
cv.waitKey()

Однако мне нужен тот же код, сделанный с. NET (C#), с использованием библиотеки EmguCV, которая является оболочкой обычный OpenCV.

Вот часть кода, которую мне удалось написать:

private bool RecognizeCO(string fileName)
{
            Image<Bgr, byte> img = new Image<Bgr, byte>(fileName);

            int cols = img.Width;

            int rows = img.Height;

            imageBox2.Image = img;

            Net netcfg = DnnInvoke.ReadNetFromTensorflow("CO.pb", "graph.pbtxt");

            netcfg.SetInput(DnnInvoke.BlobFromImage(img));

            Mat mat = netcfg.Forward();

            return false;
}

К сожалению, я понятия не имею, что делать после этого .... На самом деле, я нед тот же результат в этом C# коде, как в Python одном. Я знаю, что могу просто вызывать python скрипты из C#, но мне действительно нужно, чтобы этот код был выполнен в C# с EmguCV. Пожалуйста, помогите мне! Заранее спасибо за вашу помощь!

1 Ответ

0 голосов
/ 12 февраля 2020

Итак, наконец-то мне удалось закончить этот код ... решение было довольно простым: после получения переменной mat мы можем просто получить Data из Mat в виде числа с плавающей запятой [,,,] массив: float[,,,] flt = (float[,,,])mat.GetData(); или просто использовать одномерный массив: float[] flt = (float[])mat.GetData(jagged:false) (но я предпочитаю предыдущий)

Чем просто заставить oop бросить этот массив:

                for (int x = 0; x < flt.GetLength(2); x++)
                {
                    if (flt[0, 0, x, 2] > 0.1)
                    {
                        int left = Convert.ToInt32(flt[0, 0, x, 3] * cols);
                        int top = Convert.ToInt32(flt[0, 0, x, 4] * rows);
                        int right = Convert.ToInt32(flt[0, 0, x, 5] * cols);
                        int bottom = Convert.ToInt32(flt[0, 0, x, 6] * rows);

                        image1.Draw(new Rectangle(left, top, right - left, bottom - top), new Bgr(0, 0, 255), 2);
                    }
                }
* 1010 И, наконец, мы можем сохранить это изображение:
image1.Save("testing-1.png");

Итак, код результата будет выглядеть так:

            using (Image<Bgr, byte> image1 = new Image<Bgr, byte>("testing.png"))
            {
                int interception = 0;

                int cols = image1.Width;

                int rows = image1.Height;

                Net netcfg = DnnInvoke.ReadNetFromTensorflow(Directory.GetCurrentDirectory() + @"\fldr\CO.pb", Directory.GetCurrentDirectory() + @"\fldr\graph.pbtxt");

                netcfg.SetInput(DnnInvoke.BlobFromImage(image1.Mat, 1, new System.Drawing.Size(300, 300), default(MCvScalar), true, false));

                Mat mat = netcfg.Forward();

                float[,,,] flt = (float[,,,])mat.GetData();

                for (int x = 0; x < flt.GetLength(2); x++)
                {
                    if (flt[0, 0, x, 2] > 0.1)
                    {
                        int left = Convert.ToInt32(flt[0, 0, x, 3] * cols);
                        int top = Convert.ToInt32(flt[0, 0, x, 4] * rows);
                        int right = Convert.ToInt32(flt[0, 0, x, 5] * cols);
                        int bottom = Convert.ToInt32(flt[0, 0, x, 6] * rows);

                        image1.Draw(new Rectangle(left, top, right - left, bottom - top), new Bgr(0, 0, 255), 2);
                    }
                }

                image1.Save("testing-1.png");
            }
...