当前位置: 首页 > news >正文

安卓触摸对焦

1. 相机坐标说明

触摸对焦需要通过setFocusAreas()设置对焦区域,而该方法的参数的坐标,与屏幕坐标并不相同,需要做一个转换。

Camera(旧版相机API)来说,相机的坐标区域是一个2000*2000,原点在中心区域,该区域与相机预览画面的边界重合,如下图所示:

相机坐标与屏幕坐标

谷歌的文档对getFocusAreas()方法的描述如下(文档连接):

Gets the current focus areas. Camera driver uses the areas to decide focus.

Before using this API or setFocusAreas(java.util.List), apps should call getMaxNumFocusAreas() to know the maximum
number of focus areas first. If the value is 0, focus area is not supported.

Each focus area is a rectangle with specified weight. The direction is relative to the sensor orientation, that is,
what the sensor sees. The direction is not affected by the rotation or mirroring of Camera.setDisplayOrientation(int).
Coordinates of the rectangle range from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000) is the lower
right point. The width and height of focus areas cannot be 0 or negative.

The weight must range from 1 to 1000. The weight should be interpreted as a per-pixel weight - all pixels in the area
have the specified weight. This means a small area with the same weight as a larger area will have less influence on the
focusing than the larger area. Focus areas can partially overlap and the driver will add the weights in the overlap
region.

A special case of a null focus area list means the driver is free to select focus targets as it wants. For example,
the driver may use more signals to select focus areas and change them dynamically. Apps can set the focus area list to
null if they want the driver to completely control focusing.

Focus areas are relative to the current field of view (getZoom()). No matter what the zoom level is, (-1000,-1000)
represents the top of the currently visible camera frame. The focus area cannot be set to be outside the current field
of view, even when using zoom.

Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO, FOCUS_MODE_MACRO,
FOCUS_MODE_CONTINUOUS_VIDEO, or FOCUS_MODE_CONTINUOUS_PICTURE.

同时,设置测光区域setMeteringAreas()的方法参数的坐标,跟对焦区域的坐标是一样的,文档对getMeteringAreas()的描述如下(文档连接):

Gets the current metering areas. Camera driver uses these areas to decide exposure.

Before using this API or setMeteringAreas(java.util.List), apps should call getMaxNumMeteringAreas() to know the
maximum number of metering areas first. If the value is 0, metering area is not supported.

Each metering area is a rectangle with specified weight. The direction is relative to the sensor orientation, that is,
what the sensor sees. The direction is not affected by the rotation or mirroring of Camera.setDisplayOrientation(int).
Coordinates of the rectangle range from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000) is the lower
right point. The width and height of metering areas cannot be 0 or negative.

The weight must range from 1 to 1000, and represents a weight for every pixel in the area. This means that a large
metering area with the same weight as a smaller area will have more effect in the metering result. Metering areas can
partially overlap and the driver will add the weights in the overlap region.

A special case of a null metering area list means the driver is free to meter as it chooses. For example, the driver
may use more signals to select metering areas and change them dynamically. Apps can set the metering area list to null
if they want the driver to completely control metering.

Metering areas are relative to the current field of view (getZoom()). No matter what the zoom level is, (-1000,-1000)
represents the top of the currently visible camera frame. The metering area cannot be set to be outside the current
field of view, even when using zoom.

No matter what metering areas are, the final exposure are compensated by setExposureCompensation(int).

2. 坐标转换

根据前面对相机坐标的说明,对坐标进行转换就很简单了。

我采用的方法是:计算坐标到左上角的x、y方向的距离,与x、y轴长度的百分比,然后乘以新坐标的x、y轴长度,再根据原点与左上角的位置计算坐标。核心代码如下:

transX = (x / xMax) * 2000 - 1000
trnasY = (y / yMax) * 2000 - 1000

如果设置了预览画面的旋转角度(camera.setDisplayOrientation(orientation)),由于触摸事件中MotionEvent对象传递的是屏幕坐标,所以需要旋转。为了方便,选择在相机坐标下旋转,代码如下:

Matrix matrix = new Matrix();
matrix.setRotate(orientation);
matrix.mapRect(rectF); // rectF是相机坐标下的矩形

完整的工具类CameraAreaUtils.java代码如下:

package com.example.study.utils;import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;import com.example.study.entities.CameraAreaEntity;public class CameraAreaUtils {/*** 相机坐标区域是2000*2000,坐标原点在最中心*/private static final int CAMERA_COORDINATE_SIZE = 2000;/*** 原点到边界的距离*/private static final int CAMERA_COORDINATE_HALF_SIZE = CAMERA_COORDINATE_SIZE >> 1;/*** 根据中心点、边框边长、边框长度系数创建矩形区域** @param areaEntity 矩形区域信息* @return 矩形*/public static Rect createRect(CameraAreaEntity areaEntity) {float x = areaEntity.getX();float y = areaEntity.getY();int previewWidth = areaEntity.getPreviewWidth();int previewHeight = areaEntity.getPreviewHeight();int sideSize = (int) (areaEntity.getAreaSide() * areaEntity.getCoefficient());int left = clamp(x - sideSize / 2, 0, previewWidth);int top = clamp(y - sideSize / 2, 0, previewHeight);int right = clamp(x + sideSize / 2, 0, previewWidth);int bottom = clamp(y + sideSize / 2, 0, previewHeight);if (right - left < sideSize) {if (left == 0) {right = Math.min(sideSize, previewWidth);}if (right == previewWidth) {left = Math.max(previewWidth - sideSize, 0);}}if (bottom - top < sideSize) {if (top == 0) {bottom = Math.min(sideSize, previewHeight);}if (bottom == previewHeight) {top = Math.max(previewHeight - sideSize, 0);}}return new Rect(left, top, right, bottom);}/*** 防止坐标越界** @param position 坐标* @param min      最小值* @param max      最大值* @return 坐标*/private static int clamp(float position, int min, int max) {int pos = Math.round(position);return pos < min ? min : pos > max ? max : pos;}/*** 屏幕矩形区域转为相机矩形区域** @param areaEntity 矩形区域信息* @return 相机矩形区域*/public static Rect transToCamera(CameraAreaEntity areaEntity) {Rect rect = createRect(areaEntity);return rectFToRect(transToCamera(new RectF(rect), areaEntity));}/*** 屏幕矩形区域转为相机矩形区域** @param rectF      屏幕矩形区域* @param areaEntity 矩形区域信息* @return 相机矩形区域*/public static RectF transToCamera(RectF rectF, CameraAreaEntity areaEntity) {int previewWidth = areaEntity.getPreviewWidth();int previewHeight = areaEntity.getPreviewHeight();RectF cameraRectF = new RectF(transPositionToCameraCoordinate(rectF.left, previewWidth),transPositionToCameraCoordinate(rectF.top, previewHeight),transPositionToCameraCoordinate(rectF.right, previewWidth),transPositionToCameraCoordinate(rectF.bottom, previewHeight));// 预览画面如果有旋转,映射到相机坐标后,需要把旋转取消,才能对应真正的相机坐标Matrix matrix = new Matrix();matrix.setRotate(-1 * areaEntity.getOrientation());matrix.mapRect(cameraRectF);return cameraRectF;}/*** 将屏幕坐标转换为相机坐标** @param position 屏幕坐标某个方向的坐标值(如x)* @param srcSize  屏幕坐标对应方向的尺寸(如width)* @return 相机坐标下该方向的坐标值*/private static float transPositionToCameraCoordinate(float position, int srcSize) {return (position / srcSize) * CAMERA_COORDINATE_SIZE - CAMERA_COORDINATE_HALF_SIZE;}/*** 相机矩形区域转为屏幕矩形区域** @param rect       相机矩形区域* @param areaEntity 矩形区域信息* @return 屏幕矩形区域*/public static Rect transToScreen(Rect rect, CameraAreaEntity areaEntity) {return rectFToRect(transToScreen(new RectF(rect), areaEntity));}/*** 相机矩形区域转为屏幕矩形区域** @param rectF      相机矩形区域* @param areaEntity 矩形区域信息* @return 屏幕矩形区域*/public static RectF transToScreen(RectF rectF, CameraAreaEntity areaEntity) {int previewWidth = areaEntity.getPreviewWidth();int previewHeight = areaEntity.getPreviewHeight();// 先把相机坐标按预览的旋转角度进行旋转Matrix matrix = new Matrix();matrix.setRotate(areaEntity.getOrientation());matrix.mapRect(rectF);RectF screenRect = new RectF(transPositionToScreenCoordinate(rectF.left, previewWidth),transPositionToScreenCoordinate(rectF.top, previewHeight),transPositionToScreenCoordinate(rectF.right, previewWidth),transPositionToScreenCoordinate(rectF.bottom, previewHeight));return screenRect;}/*** 将相机坐标转换为屏幕坐标** @param position 相机坐标某个方向的坐标值(如x)* @param srcSize  相机坐标对应方向的尺寸(如width)* @return 屏幕坐标下该方向的坐标值*/private static float transPositionToScreenCoordinate(float position, int srcSize) {return ((position + CAMERA_COORDINATE_HALF_SIZE) / CAMERA_COORDINATE_SIZE) * srcSize;}/*** RectF转为Rect** @param rectF rectF对象* @return rect对象*/private static Rect rectFToRect(RectF rectF) {if (rectF == null) {return new Rect(0, 0, 0, 0);}Rect rect = new Rect();rect.left = (int) rectF.left;rect.top = (int) rectF.top;rect.right = (int) rectF.right;rect.bottom = (int) rectF.bottom;return rect;}
}

矩形区域信息类CameraAreaEntity.java:

package com.example.study.entities;public class CameraAreaEntity {/*** x轴坐标*/private float x;/*** y轴坐标*/private float y;/*** 矩形区域边长*/private int areaSide;/*** 矩形区域边长长度系数*/private float coefficient;/*** 预览画面的旋转角度*/private int orientation;/*** 屏幕宽,也就是屏幕坐标轴的x轴*/private int previewWidth;/*** 屏幕高,也就是屏幕坐标轴的y轴*/private int previewHeight;public float getX() {return x;}public void setX(float x) {this.x = x;}public float getY() {return y;}public void setY(float y) {this.y = y;}public int getAreaSide() {return areaSide;}public void setAreaSide(int areaSide) {this.areaSide = areaSide;}public float getCoefficient() {return coefficient;}public void setCoefficient(float coefficient) {this.coefficient = coefficient;}public int getOrientation() {return orientation;}public void setOrientation(int orientation) {this.orientation = orientation;}public int getPreviewWidth() {return previewWidth;}public void setPreviewWidth(int previewWidth) {this.previewWidth = previewWidth;}public int getPreviewHeight() {return previewHeight;}public void setPreviewHeight(int previewHeight) {this.previewHeight = previewHeight;}
}

3. 应用于相机

布局文件activity_camera_demo.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><SurfaceViewandroid:id="@+id/camera_preview"android:layout_width="match_parent"android:layout_height="match_parent" /><com.example.study.views.DrawViewandroid:id="@+id/camera_preview_draw"android:layout_width="match_parent"android:layout_height="match_parent" />
</FrameLayout>

绘制对焦框的DrawView.java:

package com.example.study.views;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;import androidx.annotation.Nullable;import java.util.ArrayList;
import java.util.List;public class DrawView extends View {private final Object lock = new Object();protected Paint paint;protected int color;private final List<Rect> rects = new ArrayList<>();private final List<float[]> dots = new ArrayList<>();public DrawView(Context context) {super(context);}public DrawView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public void clear() {synchronized (lock) {rects.clear();dots.clear();}postInvalidate();}public void addRect(Rect rect) {synchronized (lock) {rects.add(rect);}}public void addPoint(float x, float y) {synchronized (lock) {dots.add(new float[]{x, y});}}public void setColor(int color) {this.color = color;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);synchronized (lock) {paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setColor(color);for (Rect rect : rects) {paint.setStrokeWidth(4);canvas.drawRect(rect, paint);}for (float[] dot : dots) {paint.setStrokeWidth(10);canvas.drawPoint(dot[0], dot[1], paint);}}}
}

触摸监听类TouchListener.java:

package com.example.study.listeners;import android.graphics.Color;
import android.graphics.Rect;
import android.hardware.Camera;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;import com.example.study.entities.CameraAreaEntity;
import com.example.study.utils.CameraAreaUtils;
import com.example.study.views.DrawView;import java.util.ArrayList;
import java.util.List;public class TouchListener implements View.OnTouchListener {private static final String TAG = "TouchListener";private static final int AREA_SIDE = 210;private int orientation;private int leftMargin;private int topMargin;private Camera camera;private DrawView drawView;public TouchListener(Camera camera, int orientation, DrawView drawView, int leftMargin, int topMargin) {this.camera = camera;this.orientation = orientation;this.drawView = drawView;this.leftMargin = leftMargin;this.topMargin = topMargin;}@Overridepublic boolean onTouch(View view, MotionEvent event) {try {handlerFocusAndMetering(event);} catch (Exception exception) {Log.i(TAG, exception.getMessage());}return true;}private void handlerFocusAndMetering(MotionEvent event) {// 只有一根手指且按下时,才设置对焦区域if (event.getPointerCount() != 1 || event.getActionMasked() != MotionEvent.ACTION_DOWN) {return;}drawView.clear();drawView.setColor(Color.WHITE);boolean supportSetArea = false;CameraAreaEntity areaEntity = createAreaEntity(event);drawView.addPoint(areaEntity.getX(), areaEntity.getY());Camera.Parameters parameters = camera.getParameters();// 检查是否支持设置对焦区域if (parameters.getMaxNumFocusAreas() > 0) {areaEntity.setCoefficient(1.0f);parameters.setFocusAreas(getAreas(areaEntity));// 绘制对焦区域drawView.addRect(CameraAreaUtils.createRect(areaEntity));supportSetArea = true;}// 检查是否支持设置测光区域if (parameters.getMaxNumMeteringAreas() > 0) {areaEntity.setCoefficient(1.5f);parameters.setMeteringAreas(getAreas(areaEntity));// 绘制测光区域drawView.addRect(CameraAreaUtils.createRect(areaEntity));supportSetArea = true;}drawView.setBackgroundColor(Color.TRANSPARENT);drawView.postInvalidate();if (!supportSetArea) {return;}String currentFocusMode = parameters.getFocusMode();parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);camera.cancelAutoFocus();camera.setParameters(parameters);camera.autoFocus((success, camera) -> {drawRealArea(camera, areaEntity);Camera.Parameters params = camera.getParameters();params.setFocusMode(currentFocusMode);camera.setParameters(params);});}private CameraAreaEntity createAreaEntity(MotionEvent event) {// adjustSurface调整过左、上边距,所以需要加上边距float x = event.getX() + leftMargin;float y = event.getY() + topMargin;Camera.Parameters parameters = camera.getParameters();Camera.Size previewSize = parameters.getPreviewSize();CameraAreaEntity areaEntity = new CameraAreaEntity();areaEntity.setX(x);areaEntity.setY(y);areaEntity.setAreaSide(AREA_SIDE);areaEntity.setOrientation(orientation);areaEntity.setPreviewWidth(previewSize.height);areaEntity.setPreviewHeight(previewSize.width);return areaEntity;}private void drawRealArea(Camera camera, CameraAreaEntity areaEntity) {List<Camera.Area> focusAreas = camera.getParameters().getFocusAreas();if (focusAreas == null) {return;}drawView.clear();drawView.setColor(Color.BLUE);for (Camera.Area focusArea : focusAreas) {// previewSize的width和height正好相反Rect rect = CameraAreaUtils.transToScreen(focusArea.rect, areaEntity);drawView.addRect(rect);}drawView.setBackgroundColor(Color.TRANSPARENT);drawView.postInvalidate();}private List<Camera.Area> getAreas(CameraAreaEntity areaEntity) {List<Camera.Area> areas = new ArrayList<>();// weight:权重,取值范围为1-1000areas.add(new Camera.Area(CameraAreaUtils.transToCamera(areaEntity), 800));return areas;}
}

activity类:

package com.example.study.activities;import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.FrameLayout;import androidx.activity.ComponentActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;import com.example.study.R;
import com.example.study.listeners.TouchListener;
import com.example.study.views.DrawView;public class CameraDemoActivity extends ComponentActivity implements Camera.PreviewCallback, SurfaceHolder.Callback {private static final String TAG = "CameraDemoActivity";private static final int REQUEST_CAMERA = 1000;private static final int HEIGHT = 1920;private static final int WIDTH = 1080;private static final int ORIENTATION = 90;private int leftMargin = 0;private int topMargin = 0;private SurfaceView preview;private DrawView drawView;private Camera camera;private Camera.Parameters parameters;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(R.layout.activity_camera_demo);preview = findViewById(R.id.camera_preview);drawView = findViewById(R.id.camera_preview_draw);adjustSurface(preview);// 检查权限if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);} else {preview.getHolder().addCallback(this);}}private void adjustSurface(SurfaceView cameraPreview) {FrameLayout.LayoutParams paramSurface = (FrameLayout.LayoutParams) cameraPreview.getLayoutParams();if (getSystemService(Context.WINDOW_SERVICE) != null) {WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);Display defaultDisplay = windowManager.getDefaultDisplay();Point outPoint = new Point();defaultDisplay.getRealSize(outPoint);float screenWidth = outPoint.x;float screenHeight = outPoint.y;float rate;if (screenWidth / (float) WIDTH > screenHeight / (float) HEIGHT) {rate = screenWidth / (float) WIDTH;int targetHeight = (int) (HEIGHT * rate);paramSurface.width = FrameLayout.LayoutParams.MATCH_PARENT;paramSurface.height = targetHeight;topMargin = (int) (-(targetHeight - screenHeight) / 2);if (topMargin < 0) {paramSurface.topMargin = topMargin;}} else {rate = screenHeight / (float) HEIGHT;int targetWidth = (int) (WIDTH * rate);paramSurface.width = targetWidth;paramSurface.height = FrameLayout.LayoutParams.MATCH_PARENT;leftMargin = (int) (-(targetWidth - screenWidth) / 2);if (leftMargin < 0) {paramSurface.leftMargin = leftMargin;}}}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == REQUEST_CAMERA && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {preview.getHolder().addCallback(this);surfaceCreated(preview.getHolder());camera.setPreviewCallback(this);camera.startPreview();}}@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {Log.i(TAG, "接收到一帧图片");}@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {try {camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);parameters = camera.getParameters();// 旋转了90度,所以height、width互换parameters.setPictureSize(HEIGHT, WIDTH);parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);parameters.setPictureFormat(ImageFormat.NV21);camera.setPreviewDisplay(holder);camera.setDisplayOrientation(ORIENTATION);camera.setParameters(parameters);preview.setOnTouchListener(new TouchListener(camera, ORIENTATION, drawView, leftMargin, topMargin));} catch (Exception exception) {Log.i(TAG, exception.getMessage());}}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {if (camera != null) {camera.stopPreview();camera.setPreviewCallback(null);camera.startPreview();camera.setPreviewCallback(this);}}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {if (camera != null) {camera.stopPreview();camera.setPreviewCallback(null);camera.release();}}
}

相关文章:

安卓触摸对焦

1. 相机坐标说明 触摸对焦需要通过setFocusAreas()设置对焦区域&#xff0c;而该方法的参数的坐标&#xff0c;与屏幕坐标并不相同&#xff0c;需要做一个转换。 对Camera&#xff08;旧版相机API&#xff09;来说&#xff0c;相机的坐标区域是一个2000*2000&#xff0c;原点…...

jupyter出现“.ipynb appears to have died. It will restart automatically.”解决方法

原因 解决方法&#xff1a;更新jupyter的版本 1.打开anaconda prompt 2、更新jupyter版本 在anaconda prompt输入以下指令 conda update jupyter如图&#xff1a;...

20250108-实验+神经网络

实验3. 神经网络与反向传播算法 3.1 计算图&#xff1a;复合函数的计算图 实验要求1&#xff1a;基于numpy实现 ( y 1 , y 2 ) f ( x 1 , x 2 , x 3 ) (y_1,y_2) f(x_1,x_2,x_3) (y1​,y2​)f(x1​,x2​,x3​) 的反向传播算法&#xff08;不允许使用自动微分&#xff09;&a…...

【权限管理】CAS(Central Authentication Service)

CAS&#xff08;Central Authentication Service&#xff09;是一种广泛应用的 单点登录&#xff08;SSO&#xff09; 协议&#xff0c;它允许用户在一个集中式的身份验证系统中登录一次后&#xff0c;便可以无缝访问多个应用系统&#xff0c;而无需重复登录。CAS 通过统一的身…...

Golang笔记:使用net包进行TCP监听回环测试

文章目录 前言TCP监听回环代码演示 附&#xff1a;UDP监听回环 前言 TCP是比较基础常用的网络通讯方式&#xff0c;这篇文章将使用Go语言实现TCP监听回环测试。 本文中使用 Packet Sender 工具进行测试&#xff0c;其官网地址如下&#xff1a; https://packetsender.com/ TC…...

《浮岛风云》V1.0中文学习版

《浮岛风云》中文版https://pan.xunlei.com/s/VODadt0vSGdbrVOBEsW9Xx8iA1?pwdy7c3# 一款有着类似暗黑破坏神的战斗系统、类似最终幻想的奇幻世界和100%可破坏体素环境的动作冒险RPG。...

Day10——爬虫

爬虫概念 网络请求 爬虫分类 基本流程 请求头...

10. C语言 函数详解

本章目录: 前言1. C 语言函数概述1.1 函数的定义与结构1.2 函数声明1.3 函数调用 2. 函数参数传递2.1 传值调用2.2 传引用调用&#xff08;模拟&#xff09;2.3 引用调用&#xff08;C 特性&#xff09; 3. 内部函数与外部函数3.1 内部函数3.2 外部函数3.3 示例&#xff1a;多个…...

NRC优先级中比较特殊的—NRC0x13和NRC0x31

1、基础知识 大家都了解 NRC0x13&#xff0c;表示长度错误和格式错误 NRC0x31&#xff0c;表示DID不支持和数据格式不支持 2、为什么说这两个NRC比较特殊 看下图的标注部分&#xff1a; 2.1、先看NRC0x13 步骤一&#xff1a;仔细看是先判断Minmun Length Check &#xff0…...

ref() 和 reactive() 区别

ref() 和 reactive() 都是 Vue 3 中用于创建响应式数据的方法&#xff0c;但它们之间存在一些关键差异。 首先&#xff0c;ref() 用于创建响应式的标量值&#xff0c;比如数字、字符串、布尔值等基本数据类型&#xff0c;以及对象和数组等复杂数据类型。当你使用 ref() 时&…...

深度学习与计算机视觉 (博士)

文章目录 零、计算机视觉概述一、深度学习相关概念1.学习率η2.batchsize和epoch3.端到端(End-to-End)、序列到序列(Seq-to-Seq)4.消融实验5.学习方式6.监督学习的方式(1)有监督学习(2)强监督学习(3)弱监督学习(4)半监督学习(5)自监督学习(6)无监督学习(7)总结&#xff1a;不同…...

Sprint Boot教程之五十:Spring Boot JpaRepository 示例

Spring Boot JpaRepository 示例 Spring Boot建立在 Spring 之上&#xff0c;包含 Spring 的所有功能。由于其快速的生产就绪环境&#xff0c;使开发人员能够直接专注于逻辑&#xff0c;而不必费力配置和设置&#xff0c;因此如今它正成为开发人员的最爱。Spring Boot 是一个基…...

NaVILA:用于足式机器人导航的VLA模型

论文地址&#xff1a;https://navila-bot.github.io/static/navila_paper.pdf 项目地址&#xff1a;https://navila-bot.github.io/ 本文提出了一种名为NaVILA的机器人导航模型&#xff0c;旨在解决视觉语言导航问题&#xff0c;并允许机器人在更具挑战性和杂乱的场景中进行导…...

大语言模型提示技巧(七)-扩展

扩展是将较短的文本&#xff0c;例如一组提示或主题列表&#xff0c;输入到大型语言模型中&#xff0c;让模型生成更长的文本。我们可以利用这个特性让大语言模型生成基于某个主题的电子邮件或小论文。通过这种方式使用大语言模型&#xff0c;可以为工作与生活提供诸多便利&…...

基类指针指向派生类对象,基类指针的首地址永远指向子类从基类继承的基类首地址

文章目录 基类指针指向派生类对象&#xff0c;基类指针的首地址永远指向子类从基类继承的基类起始地址。代码代码2 基类指针指向派生类对象&#xff0c;基类指针的首地址永远指向子类从基类继承的基类起始地址。 代码 #include <iostream> using namespace std;class b…...

25年01月HarmonyOS应用基础认证最新题库

判断题 “一次开发&#xff0c;多端部署”指的是一个工程&#xff0c;一次开发上架&#xff0c;多端按需部署。为了实现这一目的&#xff0c;HarmonyOS提供了多端开发环境&#xff0c;多端开发能力以及多端分发机制。 答案&#xff1a;正确 《鸿蒙生态应用开发白皮书》全面阐释…...

wps宏js接入AI功能和接入翻译功能

wps的js越来越强大了&#xff0c;很实用的功能&#xff0c;爱了 表格wps js接入AI 表格wps js接入翻译功能&#xff0c;自定义翻译语言和目标语言...

【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件

Logstash 过滤 Filter 插件 数据从源传输到存储库的过程中&#xff0c;Logstash 过滤器能够解析各个事件&#xff0c;识别已命名的字段以构建结构&#xff0c; 并将它们转换成通用格式&#xff0c;以便进行更强大的分析和实现商业价值。 Logstash 能够动态地转换和解析数据&a…...

深度学习:Java DL4J基于RNN构建智能停车管理模型

### 深度学习&#xff1a;Java DL4J基于RNN构建智能停车管理模型 #### 引言 随着城市化进程的加速&#xff0c;停车问题日益成为城市管理的难点和痛点。传统的停车场管理方式效率低下&#xff0c;导致停车场资源无法得到充分利用&#xff0c;车主停车体验差。为了解决这些痛点…...

花生好坏缺陷识别数据集,7262张图片,支持yolo,coco json,pasical voc xml格式的标注,识别准确率在95.7%

花生好坏缺陷识别数据集,7262张图片&#xff0c;支持yolo&#xff0c;coco json&#xff0c;pasical voc xml格式的标注&#xff0c;识别准确率在95.7% 数据集分割 训练组87&#xff05; 6353图片 有效集8% 606图片 测试集4% 303图片 预处理 自动定…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...