精华内容
下载资源
问答
  • 反差式对焦图片.gif

    2020-03-18 10:07:26
    反差式对焦图片,上传后可以下载引用 CDAF的大致原理就是检测图像锐度或者等价于锐度的参数,不断推动马达寻找最清晰点实现合焦或者对焦。 缺点:对焦准确,速度慢,由于camera帧率,cpu处理速度,马达反映时间问题...
  • 反差式对焦图片.jpg

    2020-03-18 10:07:43
    反差式对焦图片,上传后可以下载引用 CDAF的大致原理就是检测图像锐度或者等价于锐度的参数,不断推动马达寻找最清晰点实现合焦或者对焦。 缺点:对焦准确,速度慢,由于camera帧率,cpu处理速度,马达反映时间问题...
  • 利用opencv 产生对焦效果 1 // 制作对焦图像 2 3 #include "stdafx.h" 4 #include <opencv2\core\core.hpp> 5 #include <opencv2\imgproc\imgproc.hpp> 6 #include <opencv2\highgui...

    利用opencv 产生对焦效果

     1 //  制作对焦图像
     2   
     3 #include "stdafx.h"  
     4 #include <opencv2\core\core.hpp>
     5 #include <opencv2\imgproc\imgproc.hpp>
     6 #include <opencv2\highgui\highgui.hpp>
     7 #include <iostream>
     8 #include <map>
     9 #include <string>
    10 #include<stdio.h>
    11 
    12 using namespace std;
    13 using namespace cv;
    14 
    15 
    16 void main()
    17 {
    18 
    19     Mat image = imread("horse_hw.jpg");
    20 
    21     Mat gray;
    22     cvtColor( image, gray, CV_BGR2GRAY);
    23 
    24     Mat binary;
    25     threshold( gray, binary, 120, 255, CV_THRESH_BINARY);
    26 
    27     vector<vector<Point>> contours;
    28     Mat binary_copy;
    29     binary.copyTo(binary_copy);
    30     findContours( binary_copy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);      //  CV_RETR_EXTERNAL 获取外轮廓 CV_CHAIN_APPROX_NONE 获取每个轮廓的像素
    31 
    32     // 遍历每一个轮廓,把多余的轮廓去掉
    33     vector<vector<Point>>::iterator it = contours.begin();
    34     while (it != contours.end())
    35     {
    36         if (it->size() < 500 || boundingRect(*it).width > image.cols)
    37         {
    38             it = contours.erase(it);
    39         }
    40         else
    41             it++;
    42     }
    43 
    44     // 通过绘制轮廓,制作掩码
    45     Mat mask(image.size(), CV_8U, Scalar(0));
    46     drawContours( mask, contours, -1, Scalar(255), CV_FILLED);
    47 
    48     Mat dst;
    49 
    50     // 对图像进行模糊处理
    51     blur(image, dst, Size(9,9));
    52 
    53     // 对目标部分进行锐化处理
    54     Mat horse;
    55     image.copyTo(horse);
    56     Mat kernel = (Mat_<float>(3,3) << 0,-1,0,-1,5,-1,0,-1,0);
    57     filter2D( horse, horse, -1, kernel);
    58 
    59     // 合成画面,把锐化后的目标部分复制到dst对应的位置
    60     horse.copyTo(dst, mask);
    61 
    62     // 显示结果(原图和结果图显示在一起)
    63     const int width = image.cols;
    64     const int height = image.rows;
    65     Mat show_image(Size(width * 2,height), CV_8UC3);
    66     // 将image拷贝到指定位置上
    67     image.copyTo(show_image(Rect( 0, 0, width, height)));
    68     // dst拷贝到指定位置上
    69     image.copyTo(show_image(Rect(width, 0, width,height)));
    70 
    71     // 显示
    72     imshow("show", show_image);
    73 
    74     waitKey(0);
    75 }

     

    转载于:https://www.cnblogs.com/zhp218/p/8646215.html

    展开全文
  • 对焦

    2012-08-25 15:05:56
    对焦的英文学名为Focus,通常数码相机有多种对焦方式,分别是自动对焦、手动对焦和多重对焦方式。 目录 自动对焦 手动对焦 多重对焦 全息自动对焦 小说《对焦》 编辑本段...

    对焦的英文学名为Focus,通常数码相机有多种对焦方式,分别是自动对焦、手动对焦和多重对焦方式。

    编辑本段自动对焦

      传统相机,采取一种类似目测测距的方式实现自动对焦,相机发射一种红外线(或其它射线),根据被摄体的反射确定被摄体的距离,然后根据测得的结果调整镜头组合,实现自动对焦。这种自动对焦方式——直接、速度快、容易实现、成本低,但有时候会出错(相机和被摄体之间有其它东西如玻璃时就无法实现自动对焦,或者在光线不足的情况下),精度也差,如今高档的相机一般已经不使用此种方式。因为是相机主动发射射线,故称主动式,又因它实际只是测距,并不通过镜头的实际成像判断是否正确结焦,所以又称为非TTL式。
      这种对焦方式相对于主动式自动对焦,后来发展了被动式自动对焦,也就是根据镜头的实际成像判断是否正确结焦,判断的依据一般是反差检测式,具体原理相当复杂。因为这种方式是通过镜头成像实现的,故称为TTL自动对焦。也正是由于这种自动对焦方式基于镜头成像实现,因此对焦精度高,出现差错的比率低,但技术复杂,速度较慢(采用超声波马达的高级自动对焦镜头除外),成本也较高。

    编辑本段手动对焦

      手动对焦,它是通过手工转动对焦环来调节相机镜头从而使拍摄出来的照片清晰的一种对焦方式,这种方式很大程度上面依赖人眼对对焦屏上的影像的判别以及拍摄者的熟练程度甚至拍摄者的视力。早期的单镜反光相机与旁轴相机基本都是使用手动对焦来完成调焦操作的。现在的准专业及专业数码相机,还有单反数码相机都设有手动对焦的功能,以配合不同的拍摄需要。对焦相当于调焦,是更改像距v,满足成像公式 1/u + 1/v = 1/f,以便在底片上结成清晰成像。 变焦是改变镜头的焦距即改变镜头的视角,其原理是在镜头的镜片中加一族活动透镜;对焦是调整像的虚实,即改变透镜和成像面的距离,达到使影像清晰目的。两个名词都带一个焦字,意义完全不同。

    编辑本段多重对焦

      很多数码相机都有多点对焦功能,或者区域对焦功能。当对焦中心不设置在图片中心的时候,可以使用多点对焦,或者多重对焦。除了设置对焦点的位置,还可以设定对焦范围,这样,用户可拍摄不同效果的图片。常见的多点对焦为5点,7点和9点对焦。

    编辑本段全息自动对焦

      全息自动对焦功能(Hologram AF),是索尼数码相机独有的功能,也是一种崭新自动对焦光学系统,采用先进激光全息摄影技术,利用激光点检测拍摄主体的边缘,就算在黑暗的环境亦能拍摄准确对焦的照片,有效拍摄距离达4.5米。
    展开全文
  • CameraMySelf android自定义相机,实现对焦图片处理,以及各种常见用法
  • 前面一篇文章Android Camera基本用法一 只是简单的介绍了Camera的基本用法,很多知识都很粗糙,今天开始一系列文章开始分别学习Camera的知识,这次的内容为Camera对焦。 1 Camera 对焦模式 Camera如果不进行对焦...

    前面一篇文章Android Camera基本用法一 只是简单的介绍了Camera的基本用法,很多知识都很粗糙,今天开始一系列文章开始分别学习Camera的知识,这次的内容为Camera对焦。

    1 Camera 对焦模式

    Camera如果不进行对焦画面会很模糊,Camera的对焦分为自动对焦和触摸对焦,但由于Android各大厂商都可以修改相关源码所以适配存在较多问题。
    Camera的对焦模式:

    • FOCUS_MODE_AUTO
      自动对焦模式,应用需要调用autoFocus(AutoFocusCallback)开始对焦,只会对焦一次,对焦成功会有回调。
    • FOCUS_MODE_INFINITY
      无穷对焦模式,应用很少,不能调用autoFocus(AutoFocusCallback)方法。
    • FOCUS_MODE_MACRO
      特写镜头对焦模式,应用需要调用autoFocus(AutoFocusCallback)开始对焦
    • FOCUS_MODE_FIXED
      固定焦点模式,焦点不可调用时都是在这种模式,如果Camera能够自动对焦,这种模式会固定焦点,通常应用于超焦距对焦。这种模式不能调用autoFocus(AutoFocusCallback)。
    • FOCUS_MODE_EDOF
      扩展景深模式,暂时不知道用法。
    • FOCUS_MODE_CONTINUOUS_VIDEO
      连续自动对焦模式,主要用于录制视频过程中,Camera会不断地尝试聚焦,这是录制视频时对焦模式的最好选择,在设置了Camera的参数后就开始自动对焦,但是调用takePicture时不一定已经对焦完成。

    从api14开始,这种模式下应用可以调用autoFocus(AutoFocusCallback)进行对焦,焦点回调函数会很快进行回调让我们知道是否对焦成功。这种模式下调用autoFocus后焦点一直是固定的。如果应用想要重新开启自动对焦,需要首先调用cancelAutoFocus。重新开始预览不会重新开启连续自动对焦。

    • FOCUS_MODE_CONTINUOUS_PICTURE
      这种模式是对 FOCUS_MODE_CONTINUOUS_VIDEO连续自动对焦应用于拍照的扩展。Camera会不停的尝试连续对焦,对焦频率会比FOCUS_MODE_CONTINUOUS_VIDEO频繁,当设置了camera参数后开始对焦。

    注意如果想要重新开始自动聚焦,需要首先调用cancelAutoFocus,然后设置自动对焦模式,在调用autoFocus(AutoFocusCallback)

    if (mCamera != null){
        mCamera.cancelAutoFocus();
        mCamera.getParameters().setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if(success){
                    Toast.makeText(Main22Activity.this,"对焦成功",Toast.LENGTH_SHORT).show();
                }else{
    
                }
            }
        });
    }
    

    该模式下可调用autoFocus(AutoFocusCallback),如果当前正在对焦扫描,focus回调函数将在它完成对焦是回调;如果没有正在对焦扫描,将立即放回。autoFocus函数调用后对焦区域是固定的,如果应用想要重新开启自动连续对焦,需要首先调用cancelAutoFocus,重新开始预览无法开启自动连续对焦,需要重新调用autoFocus,如果想要停止自动连续对焦,应用可以修改对焦模式。
    FOCUS_MODE_AUTO,FOCUS_MODE_CONTINUOUS_VIDEO,FOCUS_MODE_CONTINUOUS_PICTURE通常较为常用。

    对焦的意义就是在手机晃动,移动或者改变位置时,拍摄画面依然清晰,如果不进行对焦则画面会很模糊。

    示例代码:

    public class Main22Activity extends AppCompatActivity implements SurfaceHolder.Callback {
        private static int mOrientation = 0;
        private static int mCameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
        private SurfaceView mSurfaceView;
        private SurfaceHolder mSurfaceHolder;
        private Camera mCamera;
        private boolean havePermission = false;
        private Button btnFocus;
        private Button btnTakePic;
        private Button btnRestar;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main22);
            btnFocus = findViewById(R.id.focus);
            btnTakePic = findViewById(R.id.takepic);
            btnRestar = findViewById(R.id.restar);
    
            btnRestar.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(mCamera != null){
                        mCamera.startPreview();
                    }
                }
            });
            btnFocus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                }
            });
    
            btnTakePic.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(mCamera!= null){
                        mCamera.takePicture(null, null, new Camera.PictureCallback() {
                            @Override
                            public void onPictureTaken(byte[] data, Camera camera) {
                                // 获取Jpeg图片,并保存在sd卡上
                                String path = Environment.getExternalStorageDirectory()
                                        .getPath()  +"/focus/";
                                File pathDir = new File(path);
                                if (!pathDir.exists()){
                                    pathDir.mkdir();
                                }
                                File pictureFile = new File(path+ "focusdemo.jpg");
                                if (pictureFile.exists()){
                                    pictureFile.delete();
                                }
                                try {
                                        FileOutputStream fos = new FileOutputStream(pictureFile);
                                        fos.write(data);
                                        fos.close();
                                    } catch (Exception e) {
    
                                    }
                            }
                        });
                    }
                }
            });
           
            // Android 6.0相机动态权限检查,省略了
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                    == PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            == PackageManager.PERMISSION_GRANTED) {
                havePermission = true;
                init();
            } else {
                havePermission = false;
                ActivityCompat.requestPermissions(this,
                        new String[]{
                                Manifest.permission.CAMERA,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE
                        }, 100);
            }
        }
    
        public void init(){
            if(mSurfaceView == null){
                mSurfaceView = findViewById(R.id.surfaceview);
                mSurfaceView.setCustomEvent(new CustomSurfaceView.ONTouchEvent() {
                    @Override
                    public void onTouchEvent(MotionEvent event) {
                        handleFocus(event, mCamera);
                    }
                });
                mSurfaceHolder = mSurfaceView.getHolder();
                mSurfaceHolder.addCallback(this);
                WindowManager wm = (WindowManager) Main23Activity.this.getSystemService(Context.WINDOW_SERVICE);
                int width = wm.getDefaultDisplay().getWidth();
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mSurfaceView.getLayoutParams();
                layoutParams.width = width;
                layoutParams.height = width*4/3;
                useWidth = width;
                useHeight = width*4/3;
                mSurfaceView.setLayoutParams(layoutParams);
            }
    
        }
    
        private void initCamera() {
            if (mCamera != null){
                releaseCamera();
                System.out.println("===================releaseCamera=============");
            }
            mCamera = Camera.open(mCameraID);
            System.out.println("===================openCamera=============");
            if (mCamera != null){
                try {
                    mCamera.setPreviewDisplay(mSurfaceHolder);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setRecordingHint(true);
                {
                    //设置获取数据
                    parameters.setPreviewFormat(ImageFormat.NV21);
                    //parameters.setPreviewFormat(ImageFormat.YUV_420_888);
    
                    //通过setPreviewCallback方法监听预览的回调:
                    mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                        @Override
                        public void onPreviewFrame(byte[] bytes, Camera camera) {
                            //这里面的Bytes的数据就是NV21格式的数据,或者YUV_420_888的数据
    
    
                        }
                    });
                }
    
                if(mCameraID == Camera.CameraInfo.CAMERA_FACING_BACK){
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                }
    
                mCamera.setParameters(parameters);
    
                calculateCameraPreviewOrientation(this);
                Camera.Size tempSize = setPreviewSize(mCamera, useHeight,useWidth);
                {
                    //此处可以处理,获取到tempSize,如果tempSize和设置的SurfaceView的宽高冲突,重新设置SurfaceView的宽高
                }
    
                setPictureSize(mCamera,  useHeight,useWidth);
                mCamera.setDisplayOrientation(mOrientation);
                int degree = calculateCameraPreviewOrientation(Main23Activity.this);
                mCamera.setDisplayOrientation(degree);
                mCamera.startPreview();
            }
        }
    
     public void releaseCamera(){
            if (mCamera != null) {
                mSurfaceHolder.removeCallback(this);
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
                mCamera.lock();
                mCamera.release();
                mCamera = null;
    
            }
        }
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
          
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            //当SurfaceView变化时也需要做相应操作,这里未做相应操作
              if (havePermission){
                initCamera();
            }
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            mCamera.stopPreview();
        }
    
        private void setPictureSize(Camera camera ,int expectWidth,int expectHeight){
            Camera.Parameters parameters = camera.getParameters();
            Point point = new Point(expectWidth, expectHeight);
            Camera.Size size = findProperSize(point,parameters.getSupportedPreviewSizes());
            parameters.setPictureSize(size.width, size.height);
            camera.setParameters(parameters);
        }
    
        private Camera.Size setPreviewSize(Camera camera, int expectWidth, int expectHeight) {
            Camera.Parameters parameters = camera.getParameters();
            Point point = new Point(expectWidth, expectHeight);
            Camera.Size size = findProperSize(point,parameters.getSupportedPictureSizes());
            parameters.setPictureSize(size.width, size.height);
            camera.setParameters(parameters);
            return size;
        }
    
        /**
         * 找出最合适的尺寸,规则如下:
         * 1.将尺寸按比例分组,找出比例最接近屏幕比例的尺寸组
         * 2.在比例最接近的尺寸组中找出最接近屏幕尺寸且大于屏幕尺寸的尺寸
         * 3.如果没有找到,则忽略2中第二个条件再找一遍,应该是最合适的尺寸了
         */
        private static Camera.Size findProperSize(Point surfaceSize, List<Camera.Size> sizeList) {
            if (surfaceSize.x <= 0 || surfaceSize.y <= 0 || sizeList == null) {
                return null;
            }
    
            int surfaceWidth = surfaceSize.x;
            int surfaceHeight = surfaceSize.y;
    
            List<List<Camera.Size>> ratioListList = new ArrayList<>();
            for (Camera.Size size : sizeList) {
                addRatioList(ratioListList, size);
            }
    
            final float surfaceRatio = (float) surfaceWidth / surfaceHeight;
            List<Camera.Size> bestRatioList = null;
            float ratioDiff = Float.MAX_VALUE;
            for (List<Camera.Size> ratioList : ratioListList) {
                float ratio = (float) ratioList.get(0).width / ratioList.get(0).height;
                float newRatioDiff = Math.abs(ratio - surfaceRatio);
                if (newRatioDiff < ratioDiff) {
                    bestRatioList = ratioList;
                    ratioDiff = newRatioDiff;
                }
            }
    
            Camera.Size bestSize = null;
            int diff = Integer.MAX_VALUE;
            assert bestRatioList != null;
            for (Camera.Size size : bestRatioList) {
                int newDiff = Math.abs(size.width - surfaceWidth) + Math.abs(size.height - surfaceHeight);
                if (size.height >= surfaceHeight && newDiff < diff) {
                    bestSize = size;
                    diff = newDiff;
                }
            }
    
            if (bestSize != null) {
                return bestSize;
            }
    
            diff = Integer.MAX_VALUE;
            for (Camera.Size size : bestRatioList) {
                int newDiff = Math.abs(size.width - surfaceWidth) + Math.abs(size.height - surfaceHeight);
                if (newDiff < diff) {
                    bestSize = size;
                    diff = newDiff;
                }
            }
    
            return bestSize;
        }
    
        private static void addRatioList(List<List<Camera.Size>> ratioListList, Camera.Size size) {
            float ratio = (float) size.width / size.height;
            for (List<Camera.Size> ratioList : ratioListList) {
                float mine = (float) ratioList.get(0).width / ratioList.get(0).height;
                if (ratio == mine) {
                    ratioList.add(size);
                    return;
                }
            }
    
            List<Camera.Size> ratioList = new ArrayList<>();
            ratioList.add(size);
            ratioListList.add(ratioList);
        }
        /**
         * 排序
         * @param list
         */
        private static void sortList(List<Camera.Size> list) {
            Collections.sort(list, new Comparator<Camera.Size>() {
                @Override
                public int compare(Camera.Size pre, Camera.Size after) {
                    if (pre.width > after.width) {
                        return 1;
                    } else if (pre.width < after.width) {
                        return -1;
                    }
                    return 0;
                }
            });
        }
    
        /**
         * 设置预览角度,setDisplayOrientation本身只能改变预览的角度
         * previewFrameCallback以及拍摄出来的照片是不会发生改变的,拍摄出来的照片角度依旧不正常的
         * 拍摄的照片需要自行处理
         * 这里Nexus5X的相机简直没法吐槽,后置摄像头倒置了,切换摄像头之后就出现问题了。
         * @param activity
         */
        public static int calculateCameraPreviewOrientation(Activity activity) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(mCameraID, info);
            int rotation = activity.getWindowManager().getDefaultDisplay()
                    .getRotation();
            int degrees = 0;
            switch (rotation) {
                case Surface.ROTATION_0:
                    degrees = 0;
                    break;
                case Surface.ROTATION_90:
                    degrees = 90;
                    break;
                case Surface.ROTATION_180:
                    degrees = 180;
                    break;
                case Surface.ROTATION_270:
                    degrees = 270;
                    break;
            }
    
            int result;
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                result = (info.orientation + degrees) % 360;
                result = (360 - result) % 360;
            } else {
                result = (info.orientation - degrees + 360) % 360;
            }
            mOrientation = result;
            System.out.println("=========orienttaion============="+result);
            return result;
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            if (havePermission && mCamera != null)
           mCamera.startPreview();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            if (havePermission && mCamera != null)
          mCamera.stopPreview();
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            switch (requestCode) {
                // 相机权限
                case 100:
                    havePermission = true;
                    init();
                    break;
            }
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <SurfaceView
            android:id="@+id/surfaceview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/focus"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
            android:text="focus"/>
            <Button
                android:id="@+id/takepic"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="takePic"/>
            <Button
                android:id="@+id/restar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="restar"/>
        </LinearLayout>
    

    可以看到改变距离时画面会变得很模糊。
    在这里插入图片描述
    在这里插入图片描述

    2各种对焦模式的自动对焦应用

    统一说明:由于采用竖屏拍摄照片,保存的照片和底层传感器方向一致还是横屏的,没有对保存的数据进行旋转,所以拍出的照片被旋转了,后面会开文章对前置后置摄像头拍出的照片进行处理。

    FOCUS_MODE_AUTO 自动对焦

    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    设置这种模式之后,很多手机不会自动对焦,还是需要手动调用autoFocus函数才会对焦。

    btnFocus.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mCamera != null){
                mCamera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        if(success){
                            Toast.makeText(Main22Activity.this,"对焦成功",Toast.LENGTH_SHORT).show();
                        }else{
    
                        }
                    }
                });
            }
        }
    });
    

    这种模式很多手机上无法实现自动对焦,改变手机位置或者拍照之前需要调用autoFocus进行对焦,效果一般。拍照之前进行对焦,对焦成功进行拍照。
    在这里插入图片描述
    在这里插入图片描述

    FOCUS_MODE_CONTINUOUS_VIDEO

    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
    这种模式可以实现自动对焦,但据网上大家反映对焦时会连续闪动。
    在这里插入图片描述

    FOCUS_MODE_CONTINUOUS_PICTURE

    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

    大部分手机在这种模式下会自动对焦,网上说有部分手机不会自动对焦。
    在这里插入图片描述

    3手动对焦(触摸对焦)

    前面讲解了可以设置自动对焦模式,然后每次需要手动调用autoFocus函数进行对焦,此外Camera还提供了一种手动对焦模式叫做触摸对焦。
    触摸对焦,就是在屏幕上点击某个点,通过setFocusAreas()指定这个对焦区域,应用到相机,相机就以此点内容进行对焦,保证此点最清晰。
    利用setFocusAreas函数 ,在api14添加,api14之前只能调用autoFocus函数进行,研究setFocusAreas时官方文档指引我们看getFocusAreas()的说明。

    setFocusAreas(List focusAreas)
    只在FOCUS_MODE_AUTO,FOCUS_MODE_CONTINUOUS_VIDEO,FOCUS_MODE_CONTINUOUS_PICTURE这三种模式下有效。

    要使用setFocusAreas首先要判断是否支持设置定点对焦,api14以下是不支持的,另外还需要判断getMaxNumFocusAreas()的值,如果小于等于0也是不支持定点对焦的。
    目前市场大部分手机这个方法的返回值,前置摄像头都是0,后置摄像头都是1,说明前置摄像头一般不支持设置聚焦,而后置摄像头一般也只支持单个区域的聚焦。

    Area类用于标识感光区域(测光)和聚焦区域,用于相机计算自动曝光、自动白平衡、自动聚焦。每一个Area是一个矩形区域,有一个weight标识它的重要程度。Camera的可以设置定点对焦的区域会被映射到一个左上角为(-1000,-1000)到右下角(1000,1000)的区域上。在这个范围之外设置无效,如果area的大小为0或者weight为负是不被允许的。
    Camera.Area对象,包含两个参数:
    Rect对象,它用于指定Camera预览窗口一块矩形区域(测光区域)
    一个权重值(weight),它告诉Camera这块指定区域应该给予的测光或调焦计算的重要性等级,权重大的优先级高,权重最高为1000
    在这里插入图片描述
    Weight的取值范围必须是(1,1000),weight值越大,当我们添加多个聚焦区域时,weight大的区域起到的作用越大。

    如何把Camera坐标映射到(-1000,-1000)到(1000,1000)坐标上。

    /**
     * 转换对焦区域
     * 范围(-1000, -1000, 1000, 1000)
    * x,y是坐标位置,width,height SurfaceView的宽高,coefficient是区域比例大小
     */
    private  Rect calculateTapArea(float x, float y,  int width, int height, float coefficient) {
        float focusAreaSize = 200;
        //这段代码可以看出coefficient的作用,只是为了扩展areaSize。
        int areaSize = (int) (focusAreaSize * coefficient);
        int surfaceWidth = width;
        int surfaceHeight = height;
        //解释一下为什么*2000,因为要把surfaceView的坐标转换为范围(-1000, -1000, 1000, 1000),则SurfaceView的中心点坐标会转化为(0,0),x/surfaceWidth ,得到当前x坐标占总宽度的比例,然后乘以2000就换算成了(0,0,2000,2000)的坐标范围内,然后减去1000,就换算为了范围(-1000, -1000, 1000, 1000)的坐标。
        //得到了x,y转换后的坐标,利用areaSize就可以得到聚焦区域。
        int centerX = (int) (x / surfaceHeight * 2000 - 1000);
        int centerY = (int) (y / surfaceWidth * 2000 - 1000);
        int left = clamp(centerX - (areaSize / 2), -1000, 1000);
        int top = clamp(centerY - (areaSize / 2), -1000, 1000);
        int right = clamp(left + areaSize, -1000, 1000);
        int bottom = clamp(top + areaSize, -1000, 1000);
        return new Rect(left, top, right, bottom);
    }
    //不大于最大值,不小于最小值
    private  int clamp(int x, int min, int max) {
        if (x > max) {
            return max;
        }
        if (x < min) {
            return min;
        }
        return x;
    }
    

    在得到转换后的矩形后就可以直接通过setFocusAreas()应用到相机了?实际没这么简单。直接这么做往往不能达到理想的效果,因为Android本身的问题以及设备的差异,在常用的对焦模式为continuous-picture下,setFocusAreas()可能会不工作。目前常用的解决办法是在setFocusAreas()同时修改相机对焦模式为macro等,待对焦完毕后,再将对焦模式修改为用户之前定义的。

    使用实例:

    public class CustomSurfaceView extends SurfaceView {
    
        private ONTouchEvent mTouchEvent;
    
        public CustomSurfaceView(Context context) {
            super(context);
        }
    
        public CustomSurfaceView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (MotionEvent.ACTION_DOWN == event.getAction()){
                mTouchEvent.onTouchEvent(event);
            }
            return super.onTouchEvent(event);
        }
    
        public void setCustomEvent(ONTouchEvent onTouchEvent){
                mTouchEvent = onTouchEvent;
        }
    
        public interface ONTouchEvent{
           public void  onTouchEvent(MotionEvent event);
        }
    }
    
    mSurfaceView.setCustomEvent(new CustomSurfaceView.ONTouchEvent() {
        @Override
        public void onTouchEvent(MotionEvent event) {
            handleFocus(event, mCamera);
        }
    });
    
    private  void handleFocus(MotionEvent event, Camera camera) {
        int viewWidth = useWidth;
        int viewHeight = useHeight;
        Rect focusRect = calculateTapArea(event.getX(), event.getY(),  viewWidth, viewHeight,1.0f);
        //一定要首先取消,否则无法再次开启
        camera.cancelAutoFocus();
        Camera.Parameters params = camera.getParameters();
        if (params.getMaxNumFocusAreas() > 0) {
            List<Camera.Area> focusAreas = new ArrayList<>();
            focusAreas.add(new Camera.Area(focusRect, 800));
            params.setFocusAreas(focusAreas);
        } else {
            //focus areas not supported
        }
        //首先保存原来的对焦模式,然后设置为macro,对焦回调后设置为保存的对焦模式
        final String currentFocusMode = params.getFocusMode();
        params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
        camera.setParameters(params);
    
        camera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                //回调后 还原模式
                Camera.Parameters params = camera.getParameters();
                params.setFocusMode(currentFocusMode);
                camera.setParameters(params);
                if(success){
                    Toast.makeText(Main22Activity.this,"对焦区域对焦成功",Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    

    可以看到视频中有远近不同的两个物品,当近处物品清晰时远处不清晰,当远处物品清晰时近处不清晰,点击不同区域对焦area变换,可以转换近处和远处,如下图:
    在这里插入图片描述
    没有远近物品时:
    在这里插入图片描述

    触摸测光

    还有一种增强Camera的方式叫做触摸测光,就是在屏幕上点击某个点,相机调整曝光亮度,保证此点亮度最为合适;

    setMeteringAreas设置感光区域,也是利用Area设置测光的区域,使用之前要先调用getMaxNumMeteringAreas如果大于0说明支持测光,否则不支持无法使用。

    触摸测光与触摸对焦类似,只是作用稍有不同,触摸对焦用于改变聚焦点,触摸测光用于改变光的强弱,一般两者结合使用。
    注意:有时可能因为设置的区域过小或者权重weight过小导致效果不明显可以增大区域和weight。

    5 如何实现自动对焦

    上面说了利用对焦模式实现自动对焦会存在有的手机不支持的情况,所以要实现自动对焦还得利用触摸对焦的方式实现。
    最通用的做法就是通过监听加速度传感器的变化,传感器数值改变超过了一定范围时调用对焦函数自动对焦。
    简单实例:

    @Override
    public void onSensorChanged(SensorEvent event) {
        //手机移动一段时间后静止,然后静止一段时间后进行对焦
        // 读取加速度传感器数值,values数组0,1,2分别对应x,y,z轴的加速度
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            int x = (int) event.values[0];
            int y = (int) event.values[1];
            int z = (int) event.values[2];
    	//如果满足条件调用触摸对焦方法。
    //具体实现参考:https://github.com/WellerV/SweetCamera
    
        }
    }
    
    SweetCamera 实现方式:
    /*
    稍微解释一下SweetCamera的处理传感器的思路,通过传感器数据记录移动点和静止点,如果上一次是移动状态,现在是静止状态,且静止持续了一定时间就可以调用对焦函数进行对焦。
    */
     if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                int x = (int) event.values[0];
                int y = (int) event.values[1];
                int z = (int) event.values[2];
                mCalendar = Calendar.getInstance();
                long stamp = mCalendar.getTimeInMillis();
                int second = mCalendar.get(Calendar.SECOND);
    
                if (STATUE != STATUS_NONE) {
                    int px = Math.abs(mX - x);
                    int py = Math.abs(mY - y);
                    int pz = Math.abs(mZ - z);
    
                    double value = Math.sqrt(px * px + py * py + pz * pz);
                    if (value > 1.4) {
                        STATUE = STATUS_MOVE;
                    } else {
                        //上一次状态是move,记录静态时间点
                        if (STATUE == STATUS_MOVE) {
                            lastStaticStamp = stamp;
                            canFocusIn = true;
                        }
    
                        if (canFocusIn) {
                            if (stamp - lastStaticStamp > DELEY_DURATION) {
                                //移动后静止一段时间,可以发生对焦行为
                                if (!isFocusing) {
                                    canFocusIn = false;
                                    if (mCameraFocusListener != null) {
                                        mCameraFocusListener.onFocus();
                                    }
                                }
                            }
                        }
    
                        STATUE = STATUS_STATIC;
                    }
                } else {
                    lastStaticStamp = stamp;
                    STATUE = STATUS_STATIC;
                }
    
                mX = x;
                mY = y;
                mZ = z;
            }
    

    PS:由于手头没有太多手机,没有进行机型适配,听说魅族的会问题多一点,以上gif图有点模糊是音频,利用screenrecorder命令进行录制只能录制为mp4,之后又利用gif软件录制的MP4视频,所以画面比较模糊。

    展开全文
  • 反差对焦就是通过找对焦区域对比度最大的点作为对焦准确的点,而相位对焦则是找对焦区域相差最小的点作为对焦准确的点。 相位对焦速度更快,反差对焦成功率更高。 相位对焦实现复杂需要额外的相位检测装置或者对...

    一般来讲:单反相机全部采用相位式对焦。无反相机和消费级相机采用反差式对焦。

    图像最清晰----对比度最大-----像差最小

    反差对焦就是通过找对焦区域对比度最大的点作为对焦准确的点,而相位对焦则是找对焦区域相差最小的点作为对焦准确的点。

    相位对焦速度更快,反差对焦成功率更高。

    相位对焦实现复杂需要额外的相位检测装置或者对sensor的pixel进行重新设计,并且对光线的要求比较高;而反差对焦则实现较简单,只需要通过算法去判断对比度就行了,并且对光线的要求不是那么高。

    相位对焦

     

    相位对焦——PDAF:它的全称是Phase Detection Auto Focus,字面意思就是“相位检测自动对焦”。

    相位对焦技术在数码相机领域应用已经十分成熟,在智能手机领域则仍处于起步阶段。

    相位检测对焦系统构造相对复杂,通过分离镜头和线性传感器将图像分离出2个图像,然后通过线性传感器检测出两个图像之间的距离。

    单反相机普遍采用相位对焦系统,相比于数码单反相机上的相位对焦,手机上的相位对焦则是直接将自动对焦传感器与像素传感器直接集成在一起

    即从像素传感器上拿出左右相对的成对像素点,分别对场景中的物体进行进光量等信息的检测,通过比对左右两侧的相关值情况,便会迅速找出准确的对焦点,之后镜间马达便会一次性将镜片推动到相应位置完成对焦。

     

    在讨论PDAF功能的时候,大部分情况下我们都会声称通过该功能模组能够知道当前被摄物的距离。其实我们并非物理上知道被摄物的距离,而是通过左右shield pixel之间的差异来将被摄物映射到镜头移动距离中的某个位置。

    系统在进行对焦的时候,需要将检测到的相位差(phase difference)转换为离焦率(Defocus Value),这个转换过程应用到的表单数据称为DCC(defocus conversion coefficient)。这个转换过程应用到的表单数据称为DCC(defocus conversion coefficient)离焦转换系数。

     

    【优缺点】

    相位式对焦是通过相位检测的线性信号来判断当前的焦点位置是靠前还是靠后,并且准确的告诉镜头驱动模块,应该将镜片向哪个方向移动。而且在准确焦点位置的时候,相位检测系统可以准确的知道当前已经处于合焦状态。不需要再重复来回移动对焦镜片组。所以在速度上会比反差式对焦要快很多。

    但是,在实际拍摄中还是会出现反复对焦、难以对焦的状况。这主要就是拍摄光亮和景物反差的缘由所导致的。 相位式对焦也是被动式的对焦方式,是靠光线反射进镜头。然后传送到相应的部件上去进行识别,然后驱动对焦模块如何工作的。那么当光线弱、光线不足的情况下,对焦速度和性能会明显下降。(注意,对焦点只是采样只是焦点范围内一小部分区域的光线。也许此时你整个画面很明亮),感光器根本就无法做判断,就会出现难以对焦的局面。

     

    相位对焦虽然在对焦速度上较有优势,但是在对焦精度上却受限颇多。因为由镜头进入的光通过半反射镜,再经过折射到达对焦传感器。因此,传感器的位置要非常精确。此外,由于温度的升高或降低,机内材料会发生膨胀或伸缩,因此到AF传感器的光路长会发生变化,对焦成功率会受到影响。

    反差对焦将对焦传感器、半反射镜取消了,由此引发的光路长度变化等顾虑也就没有了,因此也提高了对焦成功率。


     

    相位对焦,它的原理是在感光元件上预留出一些遮蔽像素点,专门用来进行相位检测,通过像素之间的距离及其变化等来决定对焦的偏移值从而实现准确对焦。

    传统的单反相机拥有对焦传感器,在反光板背面还有副反光板,副反光板会把从镜头入射的部分光线送到对焦传感器上,通过测距确定焦点,再由系统控制镜头的移动完成自动对焦。

    而由于手机摄像头模组高度集成的要求,独立的对焦传感器肯定是放不进去的,于是人们直接在CMOS(感光元件)上留出一些成对儿的遮蔽像素点来进行相位检测。 遮蔽像素点由两个像素成对组成,两个像素通过微透镜各自成像。

    对焦系统根据判断信号波峰的位置可判断出镜头应该往前还是往后偏移,从而迅速准确合焦。


     

    反差式对焦

    反差对焦-CDAF- Contrast Detection Auto Focus

     

    实际中的对焦方式

     

     

    【参考文献&转载自】

    相位对焦与反差对焦 - 简书 https://www.jianshu.com/p/175dedb11d19

    摄像头模组 PDAF对焦(Phase Detection Auto Focus) - agwtpcbox - CSDN博客 https://blog.csdn.net/agwtpcbox/article/details/56676758

    手机拍照反差对焦、相位对焦和激光对焦系统解析_百度经验 https://jingyan.baidu.com/article/22a299b5c882a29e19376aad.html

    相位式对焦和反差式对焦 http://www.360doc.com/content/14/0813/10/941837_401487493.shtml

    精度高速度快厂商爱 详解PDAF相位对焦(全文)_OPPO R7_手机评测-中关村在线 http://mobile.zol.com.cn/526/5261528_all.html

     

    转载于:https://www.cnblogs.com/wxl845235800/p/9725250.html

    展开全文
  • 对焦扳手

    2017-08-03 15:08:00
    转载于:https://www.cnblogs.com/ccpblo/p/7279833.html
  • IDCardCamera 项目地址:wildma/IDCardCamera  ...简介:Android 自定义相机实现身份证拍照,并加入自动对焦图片不规则裁剪 更多:作者 提 Bug  标签:     README of English 效果 ...
  • 效果: 功能特点 自定义相机界面 支持开启闪光灯 支持手动触摸屏幕对焦 支持自动对焦 支持图片自动裁剪 支持图片手动不规则裁剪 2 使用 Step 1. 添加JitPack仓库 在项目的build.gradle添加JitPack仓库 ...
  • 对焦范围

    千次阅读 2015-01-03 14:56:13
    对焦范围 对焦范围即数码相机能清晰成像的范围,通常分为一般拍摄距离与近拍距离。相机的一般拍摄距离通常都标示为“**cm--无穷远”,而且大部分数码相机则往往还会提供近距离拍摄功能(Macro),来弥补一般拍摄...
  • 相机对焦

    2017-08-11 15:36:03
    传统的手机摄像头,其对焦采用的是反差式对焦系统,其原理是根据焦点处画面的对比度变化,寻找对比度最大时的镜头位置,也就是准确对焦的位置。 我们来分析这个对焦过程: 1.未合焦状态下,因为整个...
  • 当Glide访问同一个uri的时候,默认是有...前段时间,应公司要求实现一个自定义相机,需要有自动对焦图片不规则裁剪功能,其实难点主要也是这2个功能。经Google搜索,发现并没有现成的轮子。最后通过各种查找资料...
  • 图像对焦区域检测

    千次阅读 2016-10-06 10:29:28
     本篇是对图像对焦区域检测的笔记记录。 实现原理  主要依赖于计算标准差图像进行最清晰区域检测。 具体实现流程:1、获得对焦ok,包含近距和远距的拍摄图像pic1。 2、对pic1做区域分割,同时计算pic1的标准...
  • 1.首先android6.0以上版本要动态申请相机和文件读写权限 2.废话不啰嗦,上代码: /** * 摄像头画面采集界面 */ public class DistinguishActivity extends BaseActivity implements SurfaceHolder.Callback, ...
  • Camera手动对焦和设置对焦

    千次阅读 2019-04-28 09:25:57
    1.手动对焦 1.1思路: 我想在用户点击屏幕某个点时,以这个点做一个对焦区域,重新设定对焦区域后,会触发相机对焦,画面有明显的亮度变化。 触发图像亮度变化,实际上这已经不是对焦的范畴了,而是测光。从效果...
  • 在解决项目中相机某些机型无法自动对焦的问题时,在网上找到了一些资料,写下解决问题过程,以备查看。 Android相机实时自动对焦的完美实现 Android图像滤镜框架GPUImage从配置到应用 GPUImage for Android ...
  • 手机拍照反差对焦、相位对焦和激光对焦系统解析 参考网址:https://jingyan.baidu.com/article/22a299b5c882a29e19376aad.html 手机拍照三大对焦系统解析#资料课代表| 讲窍门# 你最常使用的拍照工具是什么?...
  • 模糊增强 检测对焦的图像区域并增强响应
  • 相机对焦算法

    热门讨论 2012-05-06 08:58:44
    本文对数码相机自动对焦系统设计中的几个关键技术—自动对焦搜索方法、评价函数、对焦窗口和镜头控制进行了深入的研究。对传统爬山算法的运行 方式和存在问题进行了全面的分析,在此基础上提出了对爬山算法的改进...
  • 自动对焦草稿

    2018-07-26 17:03:55
    自动对焦草稿--根据论文《基于边缘特征的光学图像清晰度判定》和《基于边缘特征的单帧图像清晰度判定》,但这个还不是万能的。只能说比之前用的自动对焦要准确些。
  • 激光对焦

    千次阅读 2015-12-02 16:28:33
    之前预研过激光对焦,demo已经做好了,对焦速度和准确度都还不错,但因为激光测距对矿泉水瓶等透明或反射性强的物体容易测距不准,再加上其他一些因素最终未能量产到项目,在此简单记录一下,以备查询.  主要是利用stmvl...
  • 对焦技术

    2016-01-21 16:42:09
    相位检测、自动对焦、激光、红外线、更高的像素……现在,出现在智能手机上的摄像技术已经越来越先进,并且每个厂商都在不断的尝试创新,追求比竞争对手们拥有更好的拍照效果。 三星从Galaxy S5开始使用了PDAF...
  • 然后从自相关的环形槽鉴别出光学系统点扩展函数的半径,即离焦图像的弥散斑半径,最后依据离焦图像弥散斑半径与离焦量的几何光学关系推导出光学系统正确的对焦位置。实验结果显示该方法适用了任何目标,能够以较高...
  • 自动对焦算法

    千次阅读 2019-04-11 09:30:47
    自动对焦算法算法步骤代码后记 算法 图像清晰度参考 https://blog.csdn.net/dcrmg/article/details/53543341 在实际应用中,清晰度随着对焦点的移动,呈以下图像的趋势。说白了就是有一个波峰,我们进行对焦的时候会...
  • AVCapturePhotoOutput 设置对焦 废旧旧的image调用方法,记录
  • 本文介绍了自动对焦系统中三种常用的清晰度评价函数———方差...从对焦图像高频分量多的特点出发, 提出了一种基于高通滤波评价函数的自动对焦方法, 该方法在低复杂度的同时表现出良好的对焦特点, 可以快速地实现对焦
  • WDI对焦传感器

    千次阅读 2019-07-15 10:25:09
    wdi技术的核心是wdi wise device的自主数字自动对焦传感器atf。常用在半导体检测、面板检测、光刻、激光加工、AOI线扫描等领域。 产品 面板检测 介绍: wdi自动对焦传感器产品特点: “智能传感器架构”...
  • 对焦原理

    2016-08-01 22:58:20
    关于手机拍照,应该没人不会,但是关于相机的对焦原理和算法,我相信大部分机友还是云里雾里的状态。那么今天我们就一起走进大神的世界,看看都有些什么普通玩机小白不懂的东西呢?看完一定会有

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,575
精华内容 4,230
关键字:

对焦图