[Android] [SnapdragonCamera] 单摄(横屏)阶段总结

news2024/12/23 14:35:46

        在研高通平台的单摄项目中遇到了很多适配问题,做一下初步的总结,为今后遇到相似的问题,提供参考方案。
        

1. 横屏设置相机预览显示不正常         

     1.1问题现象

             

        1.2分析与解决

             骁龙相机默认的预览方向是“portrait”。在横屏设备上显示的时候就会出现上面效果。实际操作中这样的预览效果很不友好,所以针对这种情况,需要作出如下修改: 我们以XXX-A项目为例,XXX-A的代码是共用V660C的代码,其适用的范围包含单摄像头和双摄像头的机器。所以不能直接修改AndroidManifest.xml的“screenOrientation”参数。需要做一个判断,所以其具体修改下:
a.先移除AndroidManifest.xml中的固定设置:

b. 再在主Activity: CameraActivity.java中添加相关的判断及设置:

   @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        if (Build.isLandScapeDevice()) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        if (PersistUtil.isTraceEnable())
            Trace.beginSection("CameraActivity onCreate");
        try {
            //Print version info here
            String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
            Log.d(TAG, "snapdragoncamera_version: " + versionName);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        // Check if this is in the secure camera mode.
        ....
    }

如果是屏幕横置的机器就将预览的Orientation设置成“LANDSCAPE”。如果是BBB的单一项目的代码可以将AndroidManifest.xml中的参数直接修改成“landscape”即可。
修改后的效果:

相机的菜单和拍摄按钮都调整到屏幕的下方。


2. 预览画面和菜单显示不匹配

        问题现象:

   

相机打开的预览画面是“Photo”,但是在下方的模式菜单的选项中,选中的却是“ProMode”. 造成了预览图像和菜单设置的不匹配的现象。

        分析与解决:

         造成这个问题的原因是:由于双摄像头项目在预览画面会有四个选项模式:“Video/HFR/Photo/ProMode”。而单摄项目在前置摄像头的预览时只有三个选项模式:“Video/Photo/ProMode”. 追踪Code,定位到 Camera2ModeAdapter.java 中是设置这个模式的位置:

public class Camera2ModeAdapter extends RecyclerView.Adapter<Camera2ModeAdapter.ViewHolder> {
    private List<String> mModeList;
    private int mSelectedPos = 2;  //设置默认的模式  
    private OnItemClickListener mOnItemClickListener;

    public Camera2ModeAdapter(List<String> list) {
        this.mModeList = list;
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.camera2_mode_item,
                parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mCameraModeText.setText(mModeList.get(position));
        holder.mCameraModeText.setSelected(mSelectedPos == position); //选中预览模式
        holder.mCameraModeText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener.onItemClick(position) >= 0) {
                    mSelectedPos = position;
                    notifyDataSetChanged();
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return mModeList.size();
    }

    public interface OnItemClickListener {
        int onItemClick(int mode);
    }

    public void setSelectedPosition(int position) {
        mSelectedPos = position;
        notifyDataSetChanged(); 
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        protected TextView mCameraModeText;

        public ViewHolder(View itemView) {
            super(itemView);
            mCameraModeText = (TextView) itemView.findViewById(R.id.mode_text);
        }
    }
}

mSelectedPos = 2 在四个模式下对应的是“Photo”, 但是在只有三个模式的情况下对应的mode name则是“ProMode”.

继续追Code,发现是CaptureUI.java中使用到这个adapter:

 mCameraModeAdapter = new Camera2ModeAdapter(mModule.getCameraModeList());
 mCameraModeAdapter.setOnItemClickListener(mModule.getModeItemClickListener());
 mModeSelectLayout.setAdapter(mCameraModeAdapter);

决定“mModeSelectLayout”中显示的预览模式是“mModule.getCameraModeList()” 其对应的Code则是在CaptureModule.java

public List<String> getCameraModeList() {
        ArrayList<String> cameraModes = new ArrayList<>();
        for (SceneModule sceneModule : mSceneCameraIds) {
            cameraModes.add(mSelectableModes[sceneModule.mode.ordinal()]);
        }
        return cameraModes;
}

预设的模式:

private String[] mSelectableModes = {"Video", "HFR", "Photo", "Bokeh", "SAT", "ProMode"};
...
public enum CameraMode {
        VIDEO,
        HFR,
        DEFAULT,
        RTB,
        SAT,
        PRO_MODE
    }

在初始化的时候,将六种默认的模式都加载到 mSceneCameraIds 中

for (int i = 0; i < mSelectableModes.length; i++) {
            module = new SceneModule();
            module.mode = CameraMode.values()[i];
            mSceneCameraIds.add(module);
 }

DEFAULT对应的模式则是:“Photo”。接下来程序会根据不同的情况进行筛选:

在initCameraIds()的时候,会默认将所有模式的删除属性设置成“true”:

private void initCameraIds() {
        CameraManager manager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
        boolean isFirstDefault = true;
        boolean[] removeList = new boolean[mSelectableModes.length];
        for (int i = 0; i < mSelectableModes.length; i++) {
            removeList[i] = true;
        }
 ....
        for (int i = 0; i < cameraIdList.length; i++) {
            String cameraId = cameraIdList[i];
            mCameraId[i] = cameraId;
            CameraCharacteristics characteristics;
            try {
                characteristics = manager.getCameraCharacteristics(cameraId);
            } catch (CameraAccessException e) {
                e.printStackTrace();
                continue;
            }
            isFirstDefault = setUpLocalMode(i, characteristics, removeList,
                    isFirstDefault, cameraId);
        }
 }       

setUpLocalMode 方法中会根据预设的情况进行初步的筛选:

private boolean setUpLocalMode(int cameraId, CameraCharacteristics characteristics,
                                boolean[] removeList, boolean isFirstDefault, String physicalId) {
        Byte type = 0;
        try {
            type = characteristics.get(logical_camera_type);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "setUpLocalMode no vendorTag logical_camera_type:" + logical_camera_type);
        }
        Log.d(TAG,"init cameraId " + cameraId + " | logical_camera_type = " + type +
                " | physical id = " + physicalId);
        int facing = characteristics.get(CameraCharacteristics.LENS_FACING);
        switch (type) {
            case TYPE_DEFAULT:// default
                removeList[CameraMode.DEFAULT.ordinal()] = false;
                removeList[CameraMode.VIDEO.ordinal()] = false;
                removeList[CameraMode.PRO_MODE.ordinal()] = false;
                if (facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    CaptureModule.FRONT_ID = cameraId;
                    mSceneCameraIds.get(CameraMode.DEFAULT.ordinal()).frontCameraId = cameraId;
                    mSceneCameraIds.get(CameraMode.VIDEO.ordinal()).frontCameraId = cameraId;
                    mSceneCameraIds.get(CameraMode.HFR.ordinal()).frontCameraId = cameraId;
                    mSceneCameraIds.get(CameraMode.PRO_MODE.ordinal()).frontCameraId = cameraId;
                } else {
                ...
                
          }
          ... 
      return isFirstDefault;
  }

上面部分代码将“Photo/Video/ProMode”三个模式的删除属性设置成“false"

最终确定通过下面的筛选方式将需要显示的Mode存放在mSceneCameraIds 列表中

for (int i = 0; i<mSceneCameraIds.size(); i++){
       Log.i("WKS","START----->mSceneCameraIds[" + i + "]: " + mSceneCameraIds.get(i).mode);
  }  
 
 for (int i = 0; i < removeList.length; i++) {
            if (!removeList[i]) {
                continue; //"Photo/Video/ProMode"在上面已经将改属性设置成false
            }
            for (SceneModule sceneModule : mSceneCameraIds) {
                if (sceneModule.mode.ordinal() == i) {
                    mSceneCameraIds.remove(sceneModule); //不需要的Mode在此从mSceneCameraIds中移除
                    break;
                }
            }
        }
  }   
  
  for (int i = 0; i<mSceneCameraIds.size(); i++){
       Log.i("WKS","END----->mSceneCameraIds[" + i + "]: " + mSceneCameraIds.get(i).mode);
  }  

通过上面的流程操作,可以看到筛选前mSceneCameraIds里存放的对象是:“VIDEO/HFR/DEFAULT/RTB/SAT/PRO_MODE”

筛选后则是:

“VIDEO/DEFAULT/PRO_MODE”

3. 强制断电后图片无法保存

        问题分析:

在突然断电的情况下,Android设备可能会丢失已拍摄的图片。这是因为设备的电源管理策略和文件系统缓存机制可能导致图片数据未能及时写入存储设备。

        问题解决:

在每次拍照完成后进行一次数据同步。以确保拍摄的图片和视频有同步到储存空间里:

try {
      Runtime.getRuntime().exec("sync data/misc/apexdata/com.android.media/");
 }  catch (Exception e) {
      Log.e(TAG, "Run error:" + e);
 }

在Android系统中,sync data/misc/apexdata/com.android.media/这个命令的含义是同步com.android.media模块的数据。com.android.media模块通常包含与媒体处理相关的库和资源,例如音频和视频编解码器、媒体播放服务等。

这个问题和单摄/横屏没有直接关系。在其它设备上也能复制出问题,但是由于目前在研的横屏设备没有电池,是通过AC直接供电,操作的时候如果直接移除电源就会比较容易复制出此类的现象。

4. 滑动屏幕不能切换相机的模式

        问题分析:

复制现象的时候发现,点击模式按钮进行切换的时候是正常操作的。结合问题描述的状况看,应该是滑动的时候,程序处理出现了问题。那首先我们需要定位到程序里滑动功能的位置,看其是如何定义和操作的。然后再根据其提供的线索去追踪到模式功能切换的实现位置。

        解决方案:

确定实现滑动的代码在PreviewGestures.java: 在其onScroll的方法,定义了向左isLeftSwipe,向右isRightSwipe以及上下滑动isUpSwipe的行为。

@Override
        public boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            if (e1 == null) {
                // e1 can be null if for some cases.
                return false;
            }
            if (mZoomOnly || mMode == MODE_ZOOM) return false;

            int deltaX = (int) (e1.getX() - e2.getX());
            int deltaY = (int) (e1.getY() - e2.getY());
            if((Math.abs(deltaX) > 40 || Math.abs(deltaY) > 40) && Math.abs(e1.getY()) < 1800) {
                int orientation = 0;
                if (mCaptureUI != null)
                    orientation = mCaptureUI.getOrientation();

                if (isLeftSwipe(orientation, deltaX, deltaY)) {
                    waitUntilNextDown = true;
                    if (mCaptureUI != null)
                        mCaptureUI.swipeCameraMode(-1);
                    if (mMultiCameraUI != null)
                        mMultiCameraUI.swipeCameraMode(-1);
                    return true;
                }
                if (isRightSwipe(orientation, deltaX, deltaY)) {
                    waitUntilNextDown = true;
                    if (mCaptureUI != null)
                        mCaptureUI.swipeCameraMode(1);
                    if (mMultiCameraUI != null)
                        mMultiCameraUI.swipeCameraMode(1);
                    return true;
                }
                if (isUpSwipe(orientation, deltaX, deltaY) ||
                        isDownSwipe(orientation, deltaX, deltaY)) {
                    if (Camera.getNumberOfCameras() == 1 || mModelName.equals(Build.MODEL)) {
                        return false;
                    } else {
                        if (e1.getY() < 200) {
                            return false;
                        }
                        waitUntilNextDown = true;
                        if (mCaptureUI != null)
                            mCaptureUI.switchFrontBackCamera();
                        return true;
                    }
                }
            }
            return false;
        }

继而追踪到更新UI的位置是在CaptureUI.java的 swipeCameraMode()方法里:

public void swipeCameraMode(int move) {
        Log.i("TD","---->mModule.getCameraModeSwitcherAllowed(): " + mModule.getCameraModeSwitcherAllowed());  
        if (mIsVideoUI || !mModule.getCameraModeSwitcherAllowed() ||
                mModule.getCurrentIntentMode() != CaptureModule.INTENT_MODE_NORMAL) { 
            return;
        }
        Log.i("TD","---->mModule.getCurrentModeIndex(): " + mModule.getCurrentModeIndex());
        int index = mModule.getCurrentModeIndex() + move;
        int modeListSize = mModule.getCameraModeList().size();
        if (index >= modeListSize || index == -1) {
            return;
        }
        int mode = index % modeListSize;
        mModule.setCameraModeSwitcherAllowed(false);
        mCameraModeAdapter.setSelectedPosition(mode);
        mModeSelectLayout.smoothScrollToPosition(mode);
        mModule.selectCameraMode(mode);
}       

在swipeCameraModed方法的关键位置加上log. 发现 mModule.getCurrentModeIndex()的初始值是"2".

此时如果向右滑动,move = 1,index的值就会是“3”,方法直接return. 此时如果向左滑动,move = -1,index的值为“1”。而默认的模式对应的index也是为“1”。这就造成了预览画面没有发生变化,那就无法走到下面代码的方法里去设置mCameraModeSwitcherAllowed值为“true”。而swipeCameraMoed 方法里mCameraModeSwitcherAllowed的值已经设置成“false”.后续继续滑动的话,直接就return出来了。这就造成了滑动无作用的现象。

CaptureModule.java:

private void createSession(final int id) {
        Log.d(TAG, "createSession,id: " + id + ",mPaused:" + mPaused + ",mCameraOpened:" + !mCameraOpened[id] + ",mCameraDevice:"+ (mCameraDevice[id] == null));
        if (mPaused || !mCameraOpened[id] || (mCameraDevice[id] == null)) return;
        List<Surface> list = new LinkedList<Surface>();
        mState[id] = STATE_PREVIEW;
        mControlAFMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
        try {
            // We set up a CaptureRequest.Builder with the output Surface.
            mPreviewRequestBuilder[id] = getRequestBuilder(id);
            mPreviewRequestBuilder[id].setTag(id);

            CameraCaptureSession.StateCallback captureSessionCallback =
                    new CameraCaptureSession.StateCallback() {

                        @Override
                        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                            if (mPaused || null == mCameraDevice[id] ||
                                    cameraCaptureSession == null) {
                                return;
                            }
                            Log.i(TAG, "cameracapturesession - onConfigured "+ id);
                            setCameraModeSwitcherAllowed(true);
                            // When the session is ready, we start displaying the preview.
                            ...
}                            

定位到造成问题的原因是初始状态下,由于是单个摄像头,mCurrentModeIndex 的值不能直接等于CameraMode数组里Photo对应的坐标。所以需要在下面的代码里作出如下处理:如果是单个摄像头的设备,需要将默认的mCurrentModeIndex 值设置成“1”。

if (mCurrentSceneMode == null) {
   int index = mIntentMode == INTENT_MODE_VIDEO ?
       CameraMode.VIDEO.ordinal() : CameraMode.DEFAULT.ordinal(); // CameraMode.DEFAULT.ordinal()的值是2
   if ((cameraIdList.length == 1 || mModelName.equals(Build.MODEL)) && mIntentMode != INTENT_MODE_VIDEO) {
       mCurrentModeIndex = mNextModeIndex = 1;
   } else {
       mCurrentModeIndex = mNextModeIndex = index;
   }
   mCurrentSceneMode = mSceneCameraIds.get(index);
}

public int getCurrentModeIndex() {
    return mCurrentModeIndex;
}

在后续的操作中,会通过下面的方法将index的值传递给mCurrentModeIndex

public void setNextSceneMode(int index) {
        mNextModeIndex = index;
}

private void reinitSceneMode() {
        mCurrentSceneMode = mSceneCameraIds.get(mNextModeIndex);
        mCurrentModeIndex = mNextModeIndex;
        CURRENT_MODE = mCurrentSceneMode.mode;
        CURRENT_ID = mCurrentSceneMode.getNextCameraId(CURRENT_MODE);
        Log.d(TAG, "reinitSceneMode: CURRENT_ID :" + CURRENT_ID);
}

5. 相机Promode下UI显示异常

        问题现象:

在横屏机器上,ProMode的选项发生了偏移

        分析与解决:

根据Promode中的按钮控件找到对应的布局文件pro_mode_layout.xml, 再通过布局文件的引用找到对应的java文件:src/com/android/camera/ui/OneUICameraControls.java 

在其初始化的时候有对promode的控件做了一些位置的调整:

private void initializeProMode(boolean promode) {
        if (!promode) {
            mProMode.setMode(ProMode.NO_MODE);
            mProModeLayout.setVisibility(INVISIBLE);
            return;
        }
        mProModeLayout.setVisibility(VISIBLE);
        mProModeLayout.setY(mHeight - mBottom - mProModeLayout.getHeight() - 48);
}

通过上述代码可以知晓其是对mProModeLayout 的竖直方向上做了一些调整。而对于横屏的机器遇到的问题是水平方向上发生了偏移。根据机器在水平方向上的偏移量(这边需要根据不同设备的情况作出相应的数据调整)作出相应的修改:

private void initializeProMode(boolean promode) {
        if (!promode) {
            mProMode.setMode(ProMode.NO_MODE);
            mProModeLayout.setVisibility(INVISIBLE);
            return;
        }
        mProModeLayout.setVisibility(VISIBLE);
        if (Camera.getNumberOfCameras() == 1 || mModelName.equals(Build.MODEL)) {
            if (density >= 280){
                mProModeLayout.setY(mHeight - mBottom - mProModeLayout.getHeight() + 120);
            } else {
                mProModeLayout.setY(mHeight - mBottom - mProModeLayout.getHeight());
            }
            mProModeLayout.setX(242);
        } else {
            mProModeLayout.setY(mHeight - mBottom - mProModeLayout.getHeight() - 48);
        }
 }

上面部分的代码是由于另外一个需求:

Promode的选项和功能部分会发生重叠,影响实际的功能操作。所以需要对竖直方向上坐标位置进行相应的调整。这个还需要考虑到Display Size 的调整会对其控件大小和布局的影响,所以要根据不同的density进行调整规划。 修改后的效果如下:

6.相机拍照/摄像时没有声音

        问题分析:

抓取拍照/录像时的即时log:

8-02 19:43:09.941 V/SnapCam_CaptureUI( 3687): surfaceChanged: width =1280, height = 720
08-02 19:43:09.943 E/SoundPool( 3687): error loading /product/media/audio/ui/VideoRecord.ogg
08-02 19:43:09.943 E/SoundPool( 3687): error loading /system/media/audio/ui/VideoRecord.ogg
08-02 19:43:09.943 E/MediaActionSound( 3687): load() error loading sound: 2
08-02 19:43:09.944 E/SoundPool( 3687): error loading /product/media/audio/ui/VideoStop.ogg
08-02 19:43:09.944 E/SoundPool( 3687): error loading /system/media/audio/ui/VideoStop.ogg
08-02 19:43:09.944 E/MediaActionSound( 3687): load() error loading sound: 3
08-02 19:43:09.944 E/SoundPool( 3687): error loading /product/media/audio/ui/camera_focus.ogg
08-02 19:43:09.945 E/SoundPool( 3687): error loading /system/media/audio/ui/camera_focus.ogg
08-02 19:43:09.945 E/MediaActionSound( 3687): load() error loading sound: 1
08-02 19:43:09.945 E/SoundPool( 3687): error loading /product/media/audio/ui/camera_click.ogg
08-02 19:43:09.945 E/SoundPool( 3687): error loading /system/media/audio/ui/camera_click.ogg
08-02 19:43:09.945 E/MediaActionSound( 3687): load() error loading sound: 0
08-02 19:43:09.946 D/SnapCam_CaptureModule( 3687): Chosen postproc filter id : 0

通过上面log可以看出拍照/摄像时无声的根本原因是加载音频文件的时候出现了异常。进入系统内部检查是否存在这些音频文件:

可以见当前设备的目标位置并未存放相关的资源。 正常可播放声音的机器在当前目录下会存放相关资源:

        解决方案:

找到音频文件的存放位置,将相关资源Copy到系统中:

$(LOCAL_PATH)/effects/ogg/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \

另外有些机器考虑到本身的配置比较低,加上这些资源之后可能会影响到性能。会主动移除这些功能,本案最后结合自身情况就选择不加入相关的音频资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2112393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人车防撞系统安全生产方案

根据《市场监管总局关于2021~2023年全国特种设备安全状况的通告》数据显示&#xff1a;2023年&#xff1a;全国共发生特种设备事故和相关事故71起&#xff0c;其中死亡69人。包含叉车在内的场(厂)内专用机动车辆事故29起、死亡28人&#xff0c;占事故总数的40.85%、死亡人数的4…

DBeaver 常用操作

文章目录 快捷键SQL模板xml文件删除表数据执行脚本文件导入脚本表数据的标题栏中显示中文注释 (推荐)数据库导航显示表名 (推荐)执行多行sql语句ER图说明以及避坑 快捷键 执行sql语句&#xff1a;ctrlenter sql模板(可以自定义设置)&#xff1a;sf、swhere、scount 格式化&…

【吊打面试官系列-Redis面试题】Jedis 与 Redisson 对比有什么优缺点?

大家好&#xff0c;我是锋哥。今天分享关于 【Jedis 与 Redisson 对比有什么优缺点&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Jedis 与 Redisson 对比有什么优缺点&#xff1f; Jedis 是 Redis 的 Java 实现的客户端&#xff0c;其 API 提供了比较全面的 …

【CanMV K230】圆形检测

【CanMV K230】圆形检测 什么是圆形检测圆形检测应用领域1.工业自动化2.机器人视觉3.医学图像分析4.目标识别5.质量检测6.研究和开发 K230应用相关函数官方例程HDMI屏幕使用圆形检测 本篇内容&#xff1a; 什么是圆形检测圆形检测应用领域K230应用&#xff08;包含相应函数及例…

线性代数|机器学习-P34神经网络和学习函数

文章目录 1. 神经网络2. 损失函数3. 距离矩阵 1. 神经网络 构建一个神经网络步骤如下&#xff1a; 构建一个神经网络 构造一个学习函数 F ( x , v ) F(x,v) F(x,v),x代表权重 A k , b k A_k,b_k Ak​,bk​&#xff0c;v代表样本特征向量,ReLu激活函数 v 1 R e L u [ F ( A …

Leetcode 剑指 Offer II 094.分割回文串 II

题目难度: 困难 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个字符串 s&#xff0c;请将 s 分割成一些子串&#xff0c…

Clean Minimalist GUI Pack (简约风格UI界面)

Unity 最简洁易用的 GUI 资源包。如果你在寻找资源商店上 UI 极简主义革命的发起者,你已经找到了。 这一极干净简约的 GUI 资源包是一款适合移动设备使用的游戏 UI 资源包,其中包含许多图标和元素,可用于创建具有简洁风格的完整游戏 UI。 功能: • 包括 3 种皮肤:深色、浅…

C++编程语言:基础设施:表达式(Bjarne Stroustrup)

第10章 表达式(Expressions) 目录 10.1 引言 10.2 一个桌面计算器程序 10.2.1 解析器(Parser) 10.2.2 输入(Input) 10.2.3 底层输入(Low-Level Input) 10.2.4 错误处理(Error-Handling) 10.2.5 驱动器(Driver) 10.2.6 头文件(Headers) 10.2.7 命令行参数 …

全网最火的AI技术:Rag详解

“Rag”是机器学习中的术语&#xff0c;通常指的是“Ragged Tensors”&#xff08;不规则张量&#xff09;。Ragged Tensors 是一种特殊类型的张量&#xff0c;允许不同的维度中的子张量有不同的长度或形状。这在处理诸如文本、序列数据等不定长的数据时特别有用。例如&#xf…

WebShell流量特征检测_哥斯拉篇

90后用菜刀&#xff0c;95后用蚁剑&#xff0c;00后用冰蝎和哥斯拉&#xff0c;以phpshell连接为例&#xff0c;本文主要是对后三款经典的webshell管理工具进行流量分析和检测。 什么是一句话木马&#xff1f; 1、定义 顾名思义就是执行恶意指令的木马&#xff0c;通过技术手…

Pytorch环境搭建时的各种问题

1 问题 1.一直soving environment&#xff0c;跳不出去。网络解决方案有&#xff1a;配置清华源&#xff0c;更新conda等&#xff0c;没起作用。2.下载完后&#xff0c;有3个要done的东西&#xff0c;最后那个exe开头的&#xff08;可能吧&#xff09;&#xff0c;总是报错。网…

C++常见异常汇总(一)

文章目录 1、error: ‘__s_getMD5Sum’ is not a member2、Field has incomplete type2.1 处理方案1&#xff1a;使用前置声明2.1 处理方案2&#xff1a;使用静态变量 3、无法访问基类的public函数 1、error: ‘__s_getMD5Sum’ is not a member 错误现象&#xff1a; error: …

统计学习方法与实战——统计学习方法之感知机

感知机 感知机三要素分析模型策略损失函数选择 算法原始形式对偶形式 相关问题 例子iris数据集分类实战数据集查看 显示结果sklearn 实战感知机 习题解答习题2.1解题步骤反证法 习题2.2习题2.3凸壳线性可分线性可分证明凸壳不相交证明充分性&#xff1a;凸壳不相交\Rightarrow⇒…

轻瑜伽 1.0.2 简约实用的瑜伽练习,随时随地放松身心,完全免费

轻瑜伽是一款完全免费的瑜伽练习软件&#xff0c;支持安卓。界面设计简洁明了&#xff0c;用户可以随时随地进行瑜伽练习。提供平衡性、灵活性、晨练等多种瑜伽课程&#xff0c;每种课程都有详细的动作指导&#xff0c;适合不同水平的用户。支持离线使用&#xff0c;随时随地享…

关于大模型和AIGC的36条笔记和真话

行业到底有多卷&#xff1f; 最新统计&#xff0c;中国已有130多个大模型问世&#xff0c;在网信办备案的算法模型也超过70多家。BAT等互联网巨头悉数下场发布AI大模型&#xff0c;仅2023年就有超60家创业公司拿到融资&#xff0c;产品更是布满了基础层、模型层和应用层。新一…

论文解读 | KDD2024 演化图上的森林矩阵快速计算

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者直播讲解回放&#xff01; 作者简介 孙浩鑫&#xff0c;复旦大学博士生&#xff0c;主要研究方向为大规模图上快速算法设计。 概述 森林矩阵在网络科学、观点动力学和机器学习相关应用中…

基于深度学习的气象图像分类【mobilenet+VGG16+swin_transfomer+PyQt5界面】

深度学习天气图像分类 文章目录 1 绪论1.1 研究背景1.2 国内外研究现状1.2.1 国内外研究现状1.2.2 国内外研究现状 2 相关理论基础2.1 Tensorflow框架2.2 卷积神经网络2.2.1 神经元与权值共享2.2.2 结构组成2.2.3反向传播算法 2.3 MobileNetV1网络2.4 VGG16网络2.5 Transformer…

tb-nightly库安装报错

使用pip安装&#xff08;默认清华镜像&#xff09;tb-nightly库报如下错误&#xff1a; 网上查阅资料&#xff0c;尝试了以下方式&#xff1a; 使用conda安装失败&#xff01;使用pip install tb-nightly --index-url https://pypi.org/simple安装失败最后&#xff0c;换成阿…

[Linux]:进程(上)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Linux学习 贝蒂的主页&#xff1a;Betty’s blog 1. 初识进程 1.1 进程的概念 在计算机世界中&#xff0c;进程是一个关键概念…

机器学习中的聚类艺术:探索数据的隐秘之美

一 什么是聚类 聚类是一种经典的无监督学习方法&#xff0c;无监督学习的目标是通过对无标记训练样本的学习&#xff0c;发掘和揭示数据集本身潜在的结构与规律&#xff0c;即不依赖于训练数据集的类标记信息。聚类则是试图将数据集的样本划分为若干个互不相交的类簇&#xff…