草庐IT

java - 获取 RGB 值实时相机,错误 NullPointerException

coder 2023-12-18 原文

[更新]:屏幕截图已添加。

我正在学习来自 opencv-3.4.1-android-sdk_4 的基础教程 tutorial-1-camerapreview . 我想点击屏幕并获取 x y 位置的 RGB 颜色。 我从 HERE 得到了帮助(从相机预览中的触摸事件中检索准确的 RGB 值):

获取 x y 坐标:

@SuppressWarnings("deprecation")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        x = (int)event.getX();
        y = (int)event.getY();
        return super.onTouchEvent(event);
    }

onCameraFrame 作为:

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();
        if(x != -1 && y != -1) { //if this is true, you've touched something
            rgb = mRgba.get(x,y);

            Log.d(TAG, "Touch coordinates--> " + "x: " + String.valueOf(x)
                    + " y: " + String.valueOf(y) + " \n"
                    + "RGB values--> "
                    + " Red: "   + rgb[0]
                    + " Green: " + rgb[1]
                    + " Blue: "  + rgb[2]);


            x = -1;
            y = -1;
        }

        return mRgba;
    }

我收到这些错误:

E/AndroidRuntime: FATAL EXCEPTION: Thread-904

java.lang.NullPointerException

at test.com.imagecolortest.MainActivity.onCameraFrame(MainActivity.java:104)

at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:392)

at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:373)

at java.lang.Thread.run(Thread.java:838)

注意:

行号104 (MainActivity.java:104) 是:

  • " y: " + String.valueOf(y) + " \n"

还有

有时它会在我点击屏幕左上角附近时运行。但是当我点击其他地方时它崩溃了。

有时,当它通过触摸屏幕上的一次运行时,它会给出两个日志(触发两次):(通过用相机扫描this图像)

06-22 18:09:24.515 416-806/test.com.imagecolortest D/OCVSample::Activity: Touch coordinates--> x: 340 y: 587 
                                                                             RGB values--> Red: 211.0 Green: 81.0 Blue: 220.0
06-22 18:09:24.613 416-806/test.com.imagecolortest D/OCVSample::Activity: Touch coordinates--> x: 340 y: 587 
                                                                             RGB values--> Red: 205.0 Green: 75.0 Blue: 217.0

有时当红色 rgb[0] 值为 0 时,Log.d 会触发三次。不知道为什么。

[编辑]:我们可以稍后解决这个问题,因为我们返回 super.onTouchEvent(event) 而不是返回 true。稍后会添加。

我的代码:
MainActivity.java

package test.com.imagecolortest;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements CvCameraViewListener2 {
    private static final String TAG = "OCVSample::Activity";
    private CameraBridgeViewBase mOpenCvCameraView;
    private boolean              mIsJavaCamera = true;
    private MenuItem mItemSwitchCamera = null;
    private Mat mRgba;
    int x = -1, y = -1;
    double [] rgb;
    TextView touchView;

    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS: {
                    Log.i(TAG, "OpenCV loaded successfully");
                    mOpenCvCameraView.enableView();
                } break;
                default: {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

    public MainActivity() {
        Log.i(TAG, "Instantiated new " + this.getClass());
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "called onCreate");
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_main);

        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.activity_main);
        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
        mOpenCvCameraView.setCvCameraViewListener(this);
        touchView = (TextView)findViewById(R.id.textView);
    }

    @Override
    public void onPause(){
        super.onPause();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    @Override
    public void onResume(){
        super.onResume();
        if (!OpenCVLoader.initDebug()) {
            Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
        } else {
            Log.d(TAG, "OpenCV library found inside package. Using it!");
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
    }

    public void onDestroy() {
        super.onDestroy();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    public void onCameraViewStarted(int width, int height) {
        mRgba = new Mat(height, width, CvType.CV_8UC4);
    }

    public void onCameraViewStopped() {
        mRgba.release();
    }

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();
        if(x != -1 && y != -1) { //if this is true, you've touched something
            rgb = mRgba.get(x,y);

            Log.d(TAG, "Touch coordinates--> " + "x: " + String.valueOf(x)
                    + " y: " + String.valueOf(y) + " \n"
                    + "RGB values--> "
                    + "Red: " + rgb[0]
                    + " Green: " + rgb[1]
                    + " Blue: " + rgb[2]);

// touchView.setText("Touch coordinates--> " + "x: " + String.valueOf(x)
//                    + " y: " + String.valueOf(y) + " \n" + "RGB values--> " + "Red: " + rgb[0]
//                    + " Green: " + rgb[1] + " Blue: " + rgb[2]);
            x = -1;
            y = -1;
        }

        return mRgba;
    }

    //detects touches on screen
    @SuppressWarnings("deprecation")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        x = (int)event.getX();
        y = (int)event.getY();

        //Display display = getWindowManager().getDefaultDisplay();
        //int width = display.getWidth();
        //int height = display.getHeight();
        //double [] rgb = mRgba.get(width,height);


//        touchView.setText("Touch coordinates--> " + "x: " + String.valueOf(x)
//                + " y: " + String.valueOf(y) + " \n" + "RGB values--> " + "Red: " + rgb[0]
//                + " Green: " + rgb[1] + " Blue: " + rgb[2]);

        return super.onTouchEvent(event);
    }
}

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:opencv="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <org.opencv.android.JavaCameraView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="gone"
        android:id="@+id/activity_main"
        opencv:show_fps="true"
        opencv:camera_id="any" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:id="@+id/textView"
        android:layout_gravity="left|bottom" />


</FrameLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="test.com.imagecolortest">
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.front" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        >
        <activity   android:name=".MainActivity"
                    android:screenOrientation="landscape"
                    android:configChanges="keyboardHidden|orientation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <supports-screens android:resizeable="true"
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:anyDensity="true" />

</manifest>

[更新]

我认为我没有为点击事件定义边界(宽度、高度、像素等)。当我点击屏幕的左侧时,它起作用了,但是当我点击其他角/边时(离中心很远),应用程序崩溃了。 我在屏幕上显示实时数据

Imgproc.putText() as: Imgproc.putText(mRgba,"R:"+rgb[0] + " G:"+rgb[1] +" B:"+rgb[2] + "x: " + x + " y: " + y, new Point(10,52), Core.FONT_HERSHEY_COMPLEX,.7, new Scalar(5,255,255),2,8,false ); 

而且我注意到了一些非常奇怪的行为。 y(垂直)值没问题。但是,当我从左向右滑动手指时,x 值在 0-599 范围内工作良好,当它触及 600 值时突然应用程序崩溃。 请参阅下面附上的照片:

14.93 FPS@800x600
R:134.0 G:155.0 B:151.0
x: 371 y: 488

  • 红点显示我的手指现在所在的位置。
  • 红色矩形 (实际上是正方形) 表明,当我触摸它的内部时,我的应用程序可以正常工作,但当它超出(到最右边) 时,它会崩溃。

最佳答案

CvCameraViewFrame.rgba() 返回一个 Mat,OpenCV Mat 索引首先是行,然后是列。您正在调用 rgb = mRgba.get(x,y);,因此您将 x 作为行传递,将 y 作为列传递,当 x > 时,这将超出 800x600 显示范围= 600。

https://docs.opencv.org/java/2.4.9/org/opencv/core/Mat.html#get(int,%20int) ).

关于java - 获取 RGB 值实时相机,错误 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50988869/

有关java - 获取 RGB 值实时相机,错误 NullPointerException的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  4. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  5. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  6. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  7. ruby-on-rails - 错误 : Error installing pg: ERROR: Failed to build gem native extension - 2

    我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby​​'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe

  8. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  9. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  10. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

随机推荐