2013-12-08 3 views
2

Я хочу создать простую службу WCF, которая возвращает данные глубины от датчика Kinect. Вот мой код:KinectSensor.DepthStream.OpenNextFrame возвращает NULL

[DataContract] 
public class DepthFrame 
{ 
    [DataMember] 
    public short[] depthData { get; set; } 
} 

[ServiceContract] 
public interface IKinectTools 
{  
    [OperationContract] 
    DepthFrame getDepthData(); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class KinectTools : IKinectTools 
{ 
    public DepthFrame getDepthData() 
    {    
     DepthFrame df = new DepthFrame(); 
     KinectSensor kinect = KinectSensor.KinectSensors[0]; 
     kinect.DepthStream.Enable(); 
     kinect.Start(); 
     DepthImageFrame depthFrame = kinect.DepthStream.OpenNextFrame(5); 
     df.depthData = new short[depthFrame.PixelDataLength]; 
     depthFrame.CopyPixelDataTo(df.depthData); 
     return df; 
    }    
} 

но код не работает. При запуске службы я получаю сообщение об ошибке в следующей строке:

df.depthData = new short[depthFrame.PixelDataLength]; 

потому что глубина рамки равна нулю. Почему переменная depthFrame равна null, когда я вызываю метод OpenNextFrame?


enter image description here

Заранее спасибо!

+0

Какая полная трассировка исключений, пожалуйста? –

+0

Исключение NullReferenceException не было обработано кодом пользователя. В экземпляре объекта не задана ссылка на объект. http://s12.postimg.org/eo2laxdbh/image.png –

+0

Держитесь - что-то мне пришло в голову. Когда вы говорите «услуга WCF», вы имеете в виду «работа в сеансе 0 как часть IIS»? Я был бы очень удивлен, если бы Kinect SDK был безопасен для вызова из контекста службы, поэтому, если вы это делаете, вам может понадобиться подумать о другом подходе. Многие API окон не поддерживаются при работе в контексте службы. – Stewart

ответ

1

http://msdn.microsoft.com/en-us/library/microsoft.kinect.depthimagestream.opennextframe.aspx говорит, что функция вернет значение null, если время ожидания истечет до того, как будет доступен кадр. Поскольку вы указываете время ожидания 5 мс, это, скорее всего, произойдет. Тем более, что вы только что запустили датчик, чтобы он, возможно, еще не закончил работу (часть его запуска асинхронна). Вам нужно либо указать более длительный тайм-аут для следующего кадра, либо обработать нулевой регистр.

В моей игре я опросу для нового фрейма на каждом игровом фрейме, указав нулевой тайм-аут. Если результат равен нулю, я использую последний кадр. Во время запуска игры я жду, когда первый кадр станет доступным, так что мне не придется иметь дело с граничным случаем, когда мы еще не получили первый кадр. Это аккуратно, потому что позволяет снимать частоту кадров игры из частоты кадров Kinect (что идеально значительно ниже).

+0

Я изменил время ожидания, и он все еще не работает :(Я не уверен, что лучший способ справиться с нулевым случаем, и в моем случае нет последнего фрейма! Спасибо. –

+0

Что вы увеличили время ожидания до? Как упражнение для отладки, вы можете попробовать установить его в int.MaxValue, чтобы на практике он никогда не исчезнет и не увидит, есть ли у вас кадр. Как я уже сказал - в моей игре Xbox 360, что я делаю с этим, один вызов, проходящий через INFINITE для таймаута при запуске. После этого я всегда передаю 0 для таймаута, а если он возвращает null, я просто повторно использую значение, которое я получил в последний раз. – Stewart

+0

Я пробовал разные значения, и это не сработало. также попытался использовать цикл: 'do { { depthFrame = kinect.DepthStream.OpenNextFrame (20); } while (depthFrame == null);' и я получил еще одну ошибку WCF, которая «Не удалось вызвать службу». @St ewart –