【问题标题】:WebCamTexture Coming Up With All 0s in the First Second or TwoWebCamTexture 在第一秒或第二秒内出现全 0
【发布时间】:2016-05-22 20:18:02
【问题描述】:

我正在使用 WebCamTexture,并在 Start 方法中启动它,然后运行另一个方法。我使用GetPixels() 获取像素,但是,它们都以(0, 0, 0) 出现。是否有任何解决方法或我可以等待的方法(Unity 似乎使用while 循环和WaitForSeconds 崩溃)。这是我当前的 Start 方法:

void Start () {

    rawImage = gameObject.GetComponent<RawImage> ();
    rawImageRect = rawImage.GetComponent<RectTransform> ();

    webcamTexture = new WebCamTexture();
    rawImage.texture = webcamTexture;
    rawImage.material.mainTexture = webcamTexture;

    webcamTexture.Play();

    Method ();

    loadingTextObject.SetActive (false);
    gameObject.SetActive (true);

}

void Method(){

    print (webcamTexture.GetPixels [0]);

}

这每次都会打印(0, 0, 0) 颜色。

【问题讨论】:

  • 嗨,迪伦。这是 Unity 和网络摄像头的一个众所周知的问题。您实际上需要做的是等待直到报告合理的大小。在实践中,您会跳过帧,直到 yourWebCam.width 大于 100。这里有完整的解释 answers.unity3d.com/questions/773464/…
  • 顺便说一句,现在大多数人只使用 NatCam assetstore.unity3d.com/en/#!/content/52154。 Unity 的网络摄像头软件很垃圾。这是他们“还没有做”的事情之一。准备好花费数周时间使用网络摄像头。
  • 哦,好吧,我已经在其他地方这样做了。希望这会奏效。
  • 别忘了勾选答案。
  • 那行不通。我必须结合 WaitForSeconds,检查是否报告了合理的大小,以及 WaitForEndOfFrame

标签: c# unity3d colors webcam


【解决方案1】:

在协程中处理您的网络摄像头,然后使用 yield return new WaitForSeconds(2); 等待 2 秒,然后再调用 webcamTexture.GetPixels

void Start () {

    rawImage = gameObject.GetComponent<RawImage> ();
    rawImageRect = rawImage.GetComponent<RectTransform> ();

    StartCoroutine(startWebCam());

    loadingTextObject.SetActive (false);
    gameObject.SetActive (true);

}

private IEnumerator startWebCam()
{
    webcamTexture = new WebCamTexture();
    rawImage.texture = webcamTexture;
    rawImage.material.mainTexture = webcamTexture;

    webcamTexture.Play();

    //Wait for 2 seconds
    yield return new WaitForSeconds(2);

    //Now call GetPixels
    Method();

}

void Method(){
    print (webcamTexture.GetPixels [0]);
}

或者就像乔在评论部分所说的那样。等待几秒钟是不可靠的。您可以等待宽度有东西再阅读它。只需替换

yield return new WaitForSeconds(2);

while (webcamTexture.width < 100)
{
    yield return null;
}

【讨论】:

  • 这似乎让 Unity 崩溃了。
  • @DylanSiegler Unity 哪个部分崩溃了?尽量具体。您可以通过从下到上的注释代码找到。
  • 产量返回 WaitForSeconds(2)
  • @DylanSiegler 这不是真的。其他东西正在使您的应用程序崩溃。禁用或删除附加到您的游戏对象的所有其他脚本。确保这是编辑器中唯一的脚本。再试一次,如果它再次崩溃,请编辑您的问题并将所有代码复制并粘贴到您当前的脚本中。我可以用它来找出导致崩溃的原因。还要在问题编辑中提及您使用的 Unity 版本。
  • @Programmer - 是的,不要那样做,你循环的是 WIDTH,所有的东西!在它报告一个合理的 SIZE 之前,它还没有开始工作。 Unity 没有调用“它还在工作吗”,唯一有效的是不断检查 SIZE 直到它报告一个非疯狂值。这就是要走的路!
【解决方案2】:

如果您不想等到报告或分配大小并且目标平台是 iOS(iPhone/iPad),也可以编写一个插件,通过扩展 CameraCapture 直接从 Unity 中的相机代码获取大小.mm:

- (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
{
intptr_t tex = (intptr_t)CMVideoSampling_SampleBuffer(&self->_cmVideoSampling, sampleBuffer, &self->_width, &self->_height);

_staticWebCamTexWidth = self->_width;
_staticWebCamTexWidth = self->_height;

UnityDidCaptureVideoFrame(tex, self->_userData);

if( self.firstFrameCallback!=nil ) {
    [self fireFirstFrame];
}
}

self->width / height 可以在作为插件方法添加的方法中返回,例如:

[DllImport("__Internal")]
private static extern int GetWebCamTextureWidth ();

[DllImport("__Internal")]
private static extern int GetWebCamTextureHeight ();

然后在objc代码中

extern "C" int GetWebCamTextureWidth() { return _staticWebCamTexWidth;  }
extern "C" int GetWebCamTextureHeight() { return _staticWebCamTexHeight;  }

这是我为使用统一的 iOS 社交游戏之一提出的解决方案。在 Android 上,我们采用了之前描述的方法。

【讨论】:

    【解决方案3】:

    当您掌握所请求图像的大小时,两秒钟的等待时间可能相当长。

    WebCamTexture 有一个您可以访问的所需宽度/高度,它会在调用 GetPixels 一次后保存纹理的“真实”宽度/高度。我们在两个与用户共享照片的项目中使用了名为 CameraCaptureKit (https://www.assetstore.unity3d.com/en/#!/content/56673) 的资产。

    那里使用的代码获取 WebCamTexture 并抓取每一帧的帧,直到它返回纹理的宽度和高度。

    在更新函数中调用 TryDummySnapshot 直到正确返回大小。

    // ANDREAS added this: In some cases we apparently don't get correct width and height until we have tried to read pixels
        // from the buffer.
        void TryDummySnapshot( ) {
            if(!gotAspect) {
                if( webCamTexture.width>16 ) {
                    if( Application.platform == RuntimePlatform.IPhonePlayer ) {
                        if(verbose)Debug.Log("Already got width height of WebCamTexture.");
                    } else { 
                    }
                    gotAspect = true;
                } else {
                    if(verbose)Debug.Log ("Taking dummy snapshot");
                    if( tmpImg == null ) {}
                    Color32[] c = webCamTexture.GetPixels32();
                }
            }
        }
    

    【讨论】:

    • 您是否阅读了我对webcamTexture.width &lt; 100 的回答的第二部分?他不是在拍快照,他想从相机中检索图像。破坏纹理也会减慢速度。
    • 我明白你的意思——也许这些纹理之一不应该被破坏,但它真的需要多长时间?我不知道创建和销毁第一个 Texture 的原因(当它大于 10 时)-我复制粘贴了代码。破坏纹理需要多长时间?
    • 拍摄快照与从相机中检索图像不一样吗?
    • 1。如果您不断地从相机接收像素,则不应创建和破坏纹理。 2。他没有在代码中的任何地方使用 Texture2D。他使用 UI 中的 RawImage,这是在不分配内存的情况下执行此操作的最佳方法。
    • 我评论的重点是这个问题已经解决了。您关于检查宽度的回答已经在我的回答的第二部分完成。请在我的回答中阅读 Joe 的 cmets。这回答了你在我的回答中留下的问题。
    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 2023-03-14
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多