精华内容
下载资源
问答
  • 实现 以OpenCV的JavaCameraView为例,首先需要定制自己的Camera,主要代码如下: [java]view plaincopy print? importjava.util.ArrayList; import...

    http://blog.csdn.net/candycat1992/article/details/21617741

    实现

     
    以OpenCV的JavaCameraView为例,首先需要定制自己的Camera,主要代码如下:
    [java]  view plain  copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. import org.opencv.android.JavaCameraView;  
    5.   
    6. import android.R.integer;  
    7. import android.content.Context;  
    8. import android.graphics.Rect;  
    9. import android.graphics.RectF;  
    10. import android.hardware.Camera;  
    11. import android.hardware.Camera.AutoFocusCallback;  
    12. import android.util.AttributeSet;  
    13. import android.view.MotionEvent;  
    14. import android.widget.Toast;  
    15.   
    16. public class MTCameraView extends JavaCameraView implements AutoFocusCallback {  
    17.   
    18.     public MTCameraView(Context context, int attrs) {  
    19.         super(context, attrs);  
    20.         // TODO Auto-generated constructor stub  
    21.     }  
    22.   
    23.     public List<Camera.Size> getResolutionList() {        
    24.         return  mCamera.getParameters().getSupportedPreviewSizes();        
    25.     }  
    26.       
    27.     public Camera.Size getResolution() {  
    28.         Camera.Parameters params = mCamera.getParameters();   
    29.         Camera.Size s = params.getPreviewSize();  
    30.         return s;  
    31.     }  
    32.       
    33.     public void setResolution(Camera.Size resolution) {  
    34.         disconnectCamera();  
    35.         connectCamera((int)resolution.width, (int)resolution.height);         
    36.     }  
    37.       
    38.     public void focusOnTouch(MotionEvent event) {  
    39.         Rect focusRect = calculateTapArea(event.getRawX(), event.getRawY(), 1f);  
    40.         Rect meteringRect = calculateTapArea(event.getRawX(), event.getRawY(), 1.5f);  
    41.   
    42.         Camera.Parameters parameters = mCamera.getParameters();  
    43.         parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);  
    44.           
    45.         if (parameters.getMaxNumFocusAreas() > 0) {  
    46.             List<Camera.Area> focusAreas = new ArrayList<Camera.Area>();  
    47.             focusAreas.add(new Camera.Area(focusRect, 1000));  
    48.           
    49.             parameters.setFocusAreas(focusAreas);  
    50.         }  
    51.   
    52.         if (parameters.getMaxNumMeteringAreas() > 0) {  
    53.             List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();  
    54.             meteringAreas.add(new Camera.Area(meteringRect, 1000));  
    55.               
    56.             parameters.setMeteringAreas(meteringAreas);  
    57.         }  
    58.   
    59.         mCamera.setParameters(parameters);  
    60.         mCamera.autoFocus(this);  
    61.     }  
    62.       
    63.     /** 
    64.      * Convert touch position x:y to {@link Camera.Area} position -1000:-1000 to 1000:1000. 
    65.      */  
    66.     private Rect calculateTapArea(float x, float y, float coefficient) {  
    67.         float focusAreaSize = 300;  
    68.         int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();  
    69.   
    70.         int centerX = (int) (x / getResolution().width * 2000 - 1000);  
    71.         int centerY = (int) (y / getResolution().height * 2000 - 1000);  
    72.   
    73.         int left = clamp(centerX - areaSize / 2, -1000, 1000);  
    74.         int right = clamp(left + areaSize, -1000, 1000);  
    75.         int top = clamp(centerY - areaSize / 2, -1000, 1000);  
    76.         int bottom = clamp(top + areaSize, -1000, 1000);  
    77.   
    78.         return new Rect(left, top, right, bottom);  
    79.         }  
    80.   
    81.     private int clamp(int x, int min, int max) {  
    82.         if (x > max) {  
    83.             return max;  
    84.         }  
    85.         if (x < min) {  
    86.             return min;  
    87.         }  
    88.         return x;  
    89.     }  
    90.       
    91.     public void setFocusMode (Context item, int type){  
    92.         Camera.Parameters params = mCamera.getParameters();   
    93.         List<String> FocusModes = params.getSupportedFocusModes();  
    94.   
    95.         switch (type){  
    96.         case 0:  
    97.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))  
    98.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);  
    99.             else   
    100.                 Toast.makeText(item, "Auto Mode not supported", Toast.LENGTH_SHORT).show();  
    101.             break;  
    102.         case 1:           
    103.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))  
    104.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);  
    105.             else  
    106.                 Toast.makeText(item, "Continuous Mode not supported", Toast.LENGTH_SHORT).show();  
    107.             break;  
    108.         case 2:           
    109.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_EDOF))  
    110.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_EDOF);  
    111.             else  
    112.                 Toast.makeText(item, "EDOF Mode not supported", Toast.LENGTH_SHORT).show();  
    113.             break;  
    114.         case 3:  
    115.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_FIXED))  
    116.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);  
    117.             else  
    118.                 Toast.makeText(item, "Fixed Mode not supported", Toast.LENGTH_SHORT).show();  
    119.             break;  
    120.         case 4:  
    121.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_INFINITY))  
    122.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);  
    123.             else  
    124.                 Toast.makeText(item, "Infinity Mode not supported", Toast.LENGTH_SHORT).show();  
    125.             break;  
    126.         case 5:  
    127.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_MACRO))  
    128.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);  
    129.             else  
    130.                 Toast.makeText(item, "Macro Mode not supported", Toast.LENGTH_SHORT).show();  
    131.             break;        
    132.         }  
    133.   
    134.         mCamera.setParameters(params);  
    135.     }  
    136.       
    137.     public void setFlashMode (Context item, int type){  
    138.         Camera.Parameters params = mCamera.getParameters();  
    139.         List<String> FlashModes = params.getSupportedFlashModes();  
    140.   
    141.         switch (type){  
    142.         case 0:  
    143.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO))  
    144.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);  
    145.             else  
    146.                 Toast.makeText(item, "Auto Mode not supported", Toast.LENGTH_SHORT).show();  
    147.             break;  
    148.         case 1:  
    149.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_OFF))  
    150.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);  
    151.             else  
    152.                 Toast.makeText(item, "Off Mode not supported", Toast.LENGTH_SHORT).show();            
    153.             break;  
    154.         case 2:  
    155.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_ON))  
    156.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);  
    157.             else  
    158.                 Toast.makeText(item, "On Mode not supported", Toast.LENGTH_SHORT).show();         
    159.             break;  
    160.         case 3:  
    161.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_RED_EYE))  
    162.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_RED_EYE);  
    163.             else  
    164.                 Toast.makeText(item, "Red Eye Mode not supported", Toast.LENGTH_SHORT).show();            
    165.             break;  
    166.         case 4:  
    167.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH))  
    168.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);  
    169.             else  
    170.                 Toast.makeText(item, "Torch Mode not supported", Toast.LENGTH_SHORT).show();          
    171.             break;  
    172.         }  
    173.   
    174.         mCamera.setParameters(params);  
    175.     }  
    176.   
    177.     @Override  
    178.     public void onAutoFocus(boolean arg0, Camera arg1) {  
    179.            
    180.     }  
    181. }  

    在MainActivity中需要初始化MTCamera,并且实现OnTouchListener接口,以便在触摸屏幕时可以调用onTouch函数。其中主要代码如下:
    [java]  view plain  copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. private MTCameraView mOpenCvCameraView;  
    2.   
    3. public void init() {  
    4.     mOpenCvCameraView = new MTCameraView(this, -1);  
    5.     mOpenCvCameraView.setCvCameraViewListener(this);  
    6.     mOpenCvCameraView.setFocusable(true);  
    7.     mOpenCvCameraView.setOnTouchListener(MainActivity.this);  
    8.     mOpenCvCameraView.enableView();  
    9.       
    10.     FrameLayout frame = new FrameLayout(this);  
    11.     frame.addView(mOpenCvCameraView);  
    12.       
    13.     setContentView(frame);  
    14.      }  
    15.   
    16. @Override  
    17. public boolean onTouch(View arg0, MotionEvent arg1) {  
    18.     // TODO Auto-generated method stub  
    19.     mOpenCvCameraView.focusOnTouch(arg1);  
    20.     return true;  
    21. }  

    init()函数是自定义的初始化函数,可以在onCreate时使用。由于这里需要使用OpenCV库,所以本项目是在加载完OpenCV库并判断成功后才调用init()函数的。
     
     

    解释

     
    在发生触摸事件时,MainActivity由于实现了OnTouchListener接口,因此会调用重写的onTouch函数,并把它的第二个参数MotionEvent传递给MTCamera,以便定位触摸位置。
     
    MTCamera的focusOnTouch函数继续工作。它首先根据触摸位置计算对焦和测光(metering)区域的大小(通过calculateTapArea函数),然后创建新的Camera.Parameters,并设置摄像机的对焦模式为Auto。
     
    然后,它分别判断该设备的相机是否支持设置对焦区域和测光区域,如果支持就分别为parameters设置之前计算好的聚焦和测光区域。
     
    最后,让Camera自动对焦。
     
     
    • calculateTapArea函数

      这个函数主要实现从屏幕坐标系到对焦坐标系的转换。由MotionEvent.getRowX()得到的是以屏幕坐标系(即屏幕左上角为原点,右下角为你的当前屏幕分辨率,单位是一个像素)为准的坐标,而setFocusAreas接受的List<Area>中的每一个Area的范围是(-1000,-1000)到(1000, 1000),也就是说屏幕中心为原点,左上角为(-1000,-1000),右下角为(1000,1000)。注意,如果超出这个范围的话,会报setParemeters failed的错误哦!除此之外,我们还提前定义了一个对焦框(测光框)的大小,并且接受一个参数(第三个参数coefficient)作为百分比进行调节。


    至此完成了触摸对焦的功能。
     
    但是,可以发现MTCamera里还有很大部分代码,主要是两个函数setFocusMode和setFlashMode。这两个函数,主要是因为在项目中我的图像经常是模糊的,但不知道系统支持那么对焦模式。这时,就可以使用这两个函数进行测试。这还需要在MainActivity中添加菜单栏的代码,以便进行选择。代码如下:
    [java]  view plain  copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. private List<Camera.Size> mResolutionList;  
    2.   
    3. private MenuItem[] mResolutionMenuItems;  
    4. private MenuItem[] mFocusListItems;  
    5. private MenuItem[] mFlashListItems;  
    6.   
    7. private SubMenu mResolutionMenu;  
    8. private SubMenu mFocusMenu;  
    9. private SubMenu mFlashMenu;  
    10.   
    11. @Override  
    12. public boolean onCreateOptionsMenu(Menu menu) {  
    13.     Log.i(TAG, "called onCreateOptionsMenu");  
    14.       
    15.     List<String> mFocusList = new LinkedList<String>();  
    16.  int idx =0;  
    17.   
    18.  mFocusMenu = menu.addSubMenu("Focus");  
    19.   
    20.  mFocusList.add("Auto");  
    21.  mFocusList.add("Continuous Video");  
    22.  mFocusList.add("EDOF");  
    23.  mFocusList.add("Fixed");  
    24.  mFocusList.add("Infinity");  
    25.  mFocusList.add("Makro");  
    26.  mFocusList.add("Continuous Picture");  
    27.   
    28.  mFocusListItems = new MenuItem[mFocusList.size()];  
    29.   
    30.  ListIterator<String> FocusItr = mFocusList.listIterator();  
    31.  while(FocusItr.hasNext()){  
    32.      // add the element to the mDetectorMenu submenu  
    33.      String element = FocusItr.next();  
    34.      mFocusListItems[idx] = mFocusMenu.add(2,idx,Menu.NONE,element);  
    35.      idx++;  
    36.  }  
    37.   
    38.  List<String> mFlashList = new LinkedList<String>();  
    39.  idx = 0;  
    40.   
    41.  mFlashMenu = menu.addSubMenu("Flash");  
    42.   
    43.  mFlashList.add("Auto");  
    44.  mFlashList.add("Off");  
    45.  mFlashList.add("On");  
    46.  mFlashList.add("Red-Eye");  
    47.  mFlashList.add("Torch");  
    48.   
    49.  mFlashListItems = new MenuItem[mFlashList.size()];  
    50.   
    51.  ListIterator<String> FlashItr = mFlashList.listIterator();  
    52.  while(FlashItr.hasNext()){  
    53.      // add the element to the mDetectorMenu submenu  
    54.      String element = FlashItr.next();  
    55.      mFlashListItems[idx] = mFlashMenu.add(3,idx,Menu.NONE,element);  
    56.      idx++;  
    57.  }  
    58.   
    59.  mResolutionMenu = menu.addSubMenu("Resolution");  
    60.  mResolutionList = mOpenCvCameraView.getResolutionList();  
    61.  mResolutionMenuItems = new MenuItem[mResolutionList.size()];  
    62.   
    63.  ListIterator<Camera.Size> resolutionItr = mResolutionList.listIterator();  
    64.  idx = 0;  
    65.  while(resolutionItr.hasNext()) {  
    66.      Camera.Size element = resolutionItr.next();  
    67.      mResolutionMenuItems[idx] = mResolutionMenu.add(1, idx, Menu.NONE,  
    68.              Integer.valueOf((int) element.width).toString() + "x" + Integer.valueOf((int) element.height).toString());  
    69.      idx++;  
    70.   }  
    71.   
    72.  return true;  
    73. }  
    74.   
    75. public boolean onOptionsItemSelected(MenuItem item) {  
    76.     Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);  
    77.   
    78.     if (item.getGroupId() == 1)  
    79.  {  
    80.      int id = item.getItemId();  
    81.      Camera.Size resolution = mResolutionList.get(id);  
    82.      mOpenCvCameraView.setResolution(resolution);  
    83.      resolution = mOpenCvCameraView.getResolution();  
    84.      String caption = Integer.valueOf((int) resolution.width).toString() + "x" + Integer.valueOf((int) resolution.height).toString();  
    85.      Toast.makeText(this, caption, Toast.LENGTH_SHORT).show();  
    86.  }   
    87.  else if (item.getGroupId()==2){  
    88.   
    89.     int focusType = item.getItemId();  
    90.   
    91.     mOpenCvCameraView.setFocusMode(this, focusType);  
    92.  }  
    93.  else if (item.getGroupId()==3){  
    94.   
    95.     int flashType = item.getItemId();  
    96.   
    97.     mOpenCvCameraView.setFlashMode(this, flashType);  
    98.  }  
    99.   
    100.     return true;  
    101. }  

    这样运行后,点击菜单就可以看见有三个菜篮列表:Focus(对焦模式),Flash(视频模式),Resolution(支持的分辨率)。对焦模式和视频模式中提供了几种常见的模式供选择,代码会判断当前设备是否支持该模式。而分辨率菜单栏会显示出当前设备支持的所有分辨率种类。
     
     
     

    参考

     

    转载于:https://www.cnblogs.com/jukan/p/6857881.html

    展开全文
  • 整个项目使用了OpenCV第三方库,但对于摄像机来说,和原生Camera的方法基本相同。       实现   以OpenCV的JavaCameraView为例,首先需要定制自己的Camera,主要代码如下: [java]   view ...

    参考
    http://stackoverflow.com/questions/18460647/android-setfocusarea-and-auto-focus

     

    http://blog.csdn.net/candycat1992/article/details/21617741

     

     

     

     

    写在前面

     
    最近在从零开始写一个移动端的AR系统,坑实在是太多了!!!整个项目使用了OpenCV第三方库,但对于摄像机来说,和原生Camera的方法基本相同。
     
     
     

    实现

     
    以OpenCV的JavaCameraView为例,首先需要定制自己的Camera,主要代码如下:
    [java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
     
    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. import org.opencv.android.JavaCameraView;  
    5.   
    6. import android.R.integer;  
    7. import android.content.Context;  
    8. import android.graphics.Rect;  
    9. import android.graphics.RectF;  
    10. import android.hardware.Camera;  
    11. import android.hardware.Camera.AutoFocusCallback;  
    12. import android.util.AttributeSet;  
    13. import android.view.MotionEvent;  
    14. import android.widget.Toast;  
    15.   
    16. public class MTCameraView extends JavaCameraView implements AutoFocusCallback {  
    17.   
    18.     public MTCameraView(Context context, int attrs) {  
    19.         super(context, attrs);  
    20.         // TODO Auto-generated constructor stub  
    21.     }  
    22.   
    23.     public List<Camera.Size> getResolutionList() {        
    24.         return  mCamera.getParameters().getSupportedPreviewSizes();        
    25.     }  
    26.       
    27.     public Camera.Size getResolution() {  
    28.         Camera.Parameters params = mCamera.getParameters();   
    29.         Camera.Size s = params.getPreviewSize();  
    30.         return s;  
    31.     }  
    32.       
    33.     public void setResolution(Camera.Size resolution) {  
    34.         disconnectCamera();  
    35.         connectCamera((int)resolution.width, (int)resolution.height);         
    36.     }  
    37.       
    38.     public void focusOnTouch(MotionEvent event) {  
    39.         Rect focusRect = calculateTapArea(event.getRawX(), event.getRawY(), 1f);  
    40.         Rect meteringRect = calculateTapArea(event.getRawX(), event.getRawY(), 1.5f);  
    41.   
    42.         Camera.Parameters parameters = mCamera.getParameters();  
    43.         parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);  
    44.           
    45.         if (parameters.getMaxNumFocusAreas() > 0) {  
    46.             List<Camera.Area> focusAreas = new ArrayList<Camera.Area>();  
    47.             focusAreas.add(new Camera.Area(focusRect, 1000));  
    48.           
    49.             parameters.setFocusAreas(focusAreas);  
    50.         }  
    51.   
    52.         if (parameters.getMaxNumMeteringAreas() > 0) {  
    53.             List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();  
    54.             meteringAreas.add(new Camera.Area(meteringRect, 1000));  
    55.               
    56.             parameters.setMeteringAreas(meteringAreas);  
    57.         }  
    58.   
    59.         mCamera.setParameters(parameters);  
    60.         mCamera.autoFocus(this);  
    61.     }  
    62.       
    63.     /** 
    64.      * Convert touch position x:y to {@link Camera.Area} position -1000:-1000 to 1000:1000. 
    65.      */  
    66.     private Rect calculateTapArea(float x, float y, float coefficient) {  
    67.         float focusAreaSize = 300;  
    68.         int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();  
    69.   
    70.         int centerX = (int) (x / getResolution().width * 2000 - 1000);  
    71.         int centerY = (int) (y / getResolution().height * 2000 - 1000);  
    72.   
    73.         int left = clamp(centerX - areaSize / 2, -1000, 1000);  
    74.         int right = clamp(left + areaSize, -1000, 1000);  
    75.         int top = clamp(centerY - areaSize / 2, -1000, 1000);  
    76.         int bottom = clamp(top + areaSize, -1000, 1000);  
    77.   
    78.         return new Rect(left, top, right, bottom);  
    79.         }  
    80.   
    81.     private int clamp(int x, int min, int max) {  
    82.         if (x > max) {  
    83.             return max;  
    84.         }  
    85.         if (x < min) {  
    86.             return min;  
    87.         }  
    88.         return x;  
    89.     }  
    90.       
    91.     public void setFocusMode (Context item, int type){  
    92.         Camera.Parameters params = mCamera.getParameters();   
    93.         List<String> FocusModes = params.getSupportedFocusModes();  
    94.   
    95.         switch (type){  
    96.         case 0:  
    97.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))  
    98.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);  
    99.             else   
    100.                 Toast.makeText(item, "Auto Mode not supported", Toast.LENGTH_SHORT).show();  
    101.             break;  
    102.         case 1:           
    103.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))  
    104.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);  
    105.             else  
    106.                 Toast.makeText(item, "Continuous Mode not supported", Toast.LENGTH_SHORT).show();  
    107.             break;  
    108.         case 2:           
    109.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_EDOF))  
    110.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_EDOF);  
    111.             else  
    112.                 Toast.makeText(item, "EDOF Mode not supported", Toast.LENGTH_SHORT).show();  
    113.             break;  
    114.         case 3:  
    115.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_FIXED))  
    116.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);  
    117.             else  
    118.                 Toast.makeText(item, "Fixed Mode not supported", Toast.LENGTH_SHORT).show();  
    119.             break;  
    120.         case 4:  
    121.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_INFINITY))  
    122.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);  
    123.             else  
    124.                 Toast.makeText(item, "Infinity Mode not supported", Toast.LENGTH_SHORT).show();  
    125.             break;  
    126.         case 5:  
    127.             if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_MACRO))  
    128.                 params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);  
    129.             else  
    130.                 Toast.makeText(item, "Macro Mode not supported", Toast.LENGTH_SHORT).show();  
    131.             break;        
    132.         }  
    133.   
    134.         mCamera.setParameters(params);  
    135.     }  
    136.       
    137.     public void setFlashMode (Context item, int type){  
    138.         Camera.Parameters params = mCamera.getParameters();  
    139.         List<String> FlashModes = params.getSupportedFlashModes();  
    140.   
    141.         switch (type){  
    142.         case 0:  
    143.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO))  
    144.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);  
    145.             else  
    146.                 Toast.makeText(item, "Auto Mode not supported", Toast.LENGTH_SHORT).show();  
    147.             break;  
    148.         case 1:  
    149.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_OFF))  
    150.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);  
    151.             else  
    152.                 Toast.makeText(item, "Off Mode not supported", Toast.LENGTH_SHORT).show();            
    153.             break;  
    154.         case 2:  
    155.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_ON))  
    156.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);  
    157.             else  
    158.                 Toast.makeText(item, "On Mode not supported", Toast.LENGTH_SHORT).show();         
    159.             break;  
    160.         case 3:  
    161.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_RED_EYE))  
    162.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_RED_EYE);  
    163.             else  
    164.                 Toast.makeText(item, "Red Eye Mode not supported", Toast.LENGTH_SHORT).show();            
    165.             break;  
    166.         case 4:  
    167.             if (FlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH))  
    168.                 params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);  
    169.             else  
    170.                 Toast.makeText(item, "Torch Mode not supported", Toast.LENGTH_SHORT).show();          
    171.             break;  
    172.         }  
    173.   
    174.         mCamera.setParameters(params);  
    175.     }  
    176.   
    177.     @Override  
    178.     public void onAutoFocus(boolean arg0, Camera arg1) {  
    179.            
    180.     }  
    181. }  

    在MainActivity中需要初始化MTCamera,并且实现OnTouchListener接口,以便在触摸屏幕时可以调用onTouch函数。其中主要代码如下:
    [java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
     
    1. private MTCameraView mOpenCvCameraView;  
    2.   
    3. public void init() {  
    4.     mOpenCvCameraView = new MTCameraView(this, -1);  
    5.     mOpenCvCameraView.setCvCameraViewListener(this);  
    6.     mOpenCvCameraView.setFocusable(true);  
    7.     mOpenCvCameraView.setOnTouchListener(MainActivity.this);  
    8.     mOpenCvCameraView.enableView();  
    9.       
    10.     FrameLayout frame = new FrameLayout(this);  
    11.     frame.addView(mOpenCvCameraView);  
    12.       
    13.     setContentView(frame);  
    14.      }  
    15.   
    16. @Override  
    17. public boolean onTouch(View arg0, MotionEvent arg1) {  
    18.     // TODO Auto-generated method stub  
    19.     mOpenCvCameraView.focusOnTouch(arg1);  
    20.     return true;  
    21. }  

    init()函数是自定义的初始化函数,可以在onCreate时使用。由于这里需要使用OpenCV库,所以本项目是在加载完OpenCV库并判断成功后才调用init()函数的。
     
     

    解释

     
    在发生触摸事件时,MainActivity由于实现了OnTouchListener接口,因此会调用重写的onTouch函数,并把它的第二个参数MotionEvent传递给MTCamera,以便定位触摸位置。
     
    MTCamera的focusOnTouch函数继续工作。它首先根据触摸位置计算对焦和测光(metering)区域的大小(通过calculateTapArea函数),然后创建新的Camera.Parameters,并设置摄像机的对焦模式为Auto。
     
    然后,它分别判断该设备的相机是否支持设置对焦区域和测光区域,如果支持就分别为parameters设置之前计算好的聚焦和测光区域。
     
    最后,让Camera自动对焦。
     
     
    • calculateTapArea函数

      这个函数主要实现从屏幕坐标系到对焦坐标系的转换。由MotionEvent.getRowX()得到的是以屏幕坐标系(即屏幕左上角为原点,右下角为你的当前屏幕分辨率,单位是一个像素)为准的坐标,而setFocusAreas接受的List<Area>中的每一个Area的范围是(-1000,-1000)到(1000, 1000),也就是说屏幕中心为原点,左上角为(-1000,-1000),右下角为(1000,1000)。注意,如果超出这个范围的话,会报setParemeters failed的错误哦!除此之外,我们还提前定义了一个对焦框(测光框)的大小,并且接受一个参数(第三个参数coefficient)作为百分比进行调节。


    至此完成了触摸对焦的功能。
     
    但是,可以发现MTCamera里还有很大部分代码,主要是两个函数setFocusMode和setFlashMode。这两个函数,主要是因为在项目中我的图像经常是模糊的,但不知道系统支持那么对焦模式。这时,就可以使用这两个函数进行测试。这还需要在MainActivity中添加菜单栏的代码,以便进行选择。代码如下:
    [java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
     
    1. private List<Camera.Size> mResolutionList;  
    2.   
    3. private MenuItem[] mResolutionMenuItems;  
    4. private MenuItem[] mFocusListItems;  
    5. private MenuItem[] mFlashListItems;  
    6.   
    7. private SubMenu mResolutionMenu;  
    8. private SubMenu mFocusMenu;  
    9. private SubMenu mFlashMenu;  
    10.   
    11. @Override  
    12. public boolean onCreateOptionsMenu(Menu menu) {  
    13.     Log.i(TAG, "called onCreateOptionsMenu");  
    14.       
    15.     List<String> mFocusList = new LinkedList<String>();  
    16.  int idx =0;  
    17.   
    18.  mFocusMenu = menu.addSubMenu("Focus");  
    19.   
    20.  mFocusList.add("Auto");  
    21.  mFocusList.add("Continuous Video");  
    22.  mFocusList.add("EDOF");  
    23.  mFocusList.add("Fixed");  
    24.  mFocusList.add("Infinity");  
    25.  mFocusList.add("Makro");  
    26.  mFocusList.add("Continuous Picture");  
    27.   
    28.  mFocusListItems = new MenuItem[mFocusList.size()];  
    29.   
    30.  ListIterator<String> FocusItr = mFocusList.listIterator();  
    31.  while(FocusItr.hasNext()){  
    32.      // add the element to the mDetectorMenu submenu  
    33.      String element = FocusItr.next();  
    34.      mFocusListItems[idx] = mFocusMenu.add(2,idx,Menu.NONE,element);  
    35.      idx++;  
    36.  }  
    37.   
    38.  List<String> mFlashList = new LinkedList<String>();  
    39.  idx = 0;  
    40.   
    41.  mFlashMenu = menu.addSubMenu("Flash");  
    42.   
    43.  mFlashList.add("Auto");  
    44.  mFlashList.add("Off");  
    45.  mFlashList.add("On");  
    46.  mFlashList.add("Red-Eye");  
    47.  mFlashList.add("Torch");  
    48.   
    49.  mFlashListItems = new MenuItem[mFlashList.size()];  
    50.   
    51.  ListIterator<String> FlashItr = mFlashList.listIterator();  
    52.  while(FlashItr.hasNext()){  
    53.      // add the element to the mDetectorMenu submenu  
    54.      String element = FlashItr.next();  
    55.      mFlashListItems[idx] = mFlashMenu.add(3,idx,Menu.NONE,element);  
    56.      idx++;  
    57.  }  
    58.   
    59.  mResolutionMenu = menu.addSubMenu("Resolution");  
    60.  mResolutionList = mOpenCvCameraView.getResolutionList();  
    61.  mResolutionMenuItems = new MenuItem[mResolutionList.size()];  
    62.   
    63.  ListIterator<Camera.Size> resolutionItr = mResolutionList.listIterator();  
    64.  idx = 0;  
    65.  while(resolutionItr.hasNext()) {  
    66.      Camera.Size element = resolutionItr.next();  
    67.      mResolutionMenuItems[idx] = mResolutionMenu.add(1, idx, Menu.NONE,  
    68.              Integer.valueOf((int) element.width).toString() + "x" + Integer.valueOf((int) element.height).toString());  
    69.      idx++;  
    70.   }  
    71.   
    72.  return true;  
    73. }  
    74.   
    75. public boolean onOptionsItemSelected(MenuItem item) {  
    76.     Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);  
    77.   
    78.     if (item.getGroupId() == 1)  
    79.  {  
    80.      int id = item.getItemId();  
    81.      Camera.Size resolution = mResolutionList.get(id);  
    82.      mOpenCvCameraView.setResolution(resolution);  
    83.      resolution = mOpenCvCameraView.getResolution();  
    84.      String caption = Integer.valueOf((int) resolution.width).toString() + "x" + Integer.valueOf((int) resolution.height).toString();  
    85.      Toast.makeText(this, caption, Toast.LENGTH_SHORT).show();  
    86.  }   
    87.  else if (item.getGroupId()==2){  
    88.   
    89.     int focusType = item.getItemId();  
    90.   
    91.     mOpenCvCameraView.setFocusMode(this, focusType);  
    92.  }  
    93.  else if (item.getGroupId()==3){  
    94.   
    95.     int flashType = item.getItemId();  
    96.   
    97.     mOpenCvCameraView.setFlashMode(this, flashType);  
    98.  }  
    99.   
    100.     return true;  
    101. }  

    这样运行后,点击菜单就可以看见有三个菜篮列表:Focus(对焦模式),Flash(视频模式),Resolution(支持的分辨率)。对焦模式和视频模式中提供了几种常见的模式供选择,代码会判断当前设备是否支持该模式。而分辨率菜单栏会显示出当前设备支持的所有分辨率种类。
     
     
     

    参考

     
    展开全文
  • 相机自动对焦 OpenCV 图像清晰度评价

    千次阅读 2019-04-26 17:31:21
    OpenCV 图像清晰度评价(相机自动对焦) 版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/dcrmg/article/details/53543341 相机的自动对焦要求相机根据拍摄环境和场景的变化,通过相机内部...

    原文:https://blog.csdn.net/dcrmg/article/details/53543341

    OpenCV 图像清晰度评价(相机自动对焦)

    版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/dcrmg/article/details/53543341

    相机的自动对焦要求相机根据拍摄环境和场景的变化,通过相机内部的微型驱动马达,自动调节相机镜头和CCD之间的距离,保证像平面正好投影到CCD的成像表面上。这时候物体的成像比较清晰,图像细节信息丰富。

    相机自动对焦的过程,其实就是对成像清晰度评价的过程,对焦不准确,拍摄出来的图像清晰度低,视觉效果模糊,如果是在工业检测测量领域,对焦不准导致的后果可能是致命的;对焦准确的图像清晰度较高,层次鲜明,对比度高。

     

    图像清晰度评价算法有很多种,在空域中,主要思路是考察图像的领域对比度,即相邻像素间的灰度特征的梯度差;在频域中,主要思路是考察图像的频率分量,对焦清晰的图像高频分量较多,对焦模糊的图像低频分量较多。

    这里实现3种清晰度评价方法,分别是Tenengrad梯度方法、Laplacian梯度方法和方差方法。

    Tenengrad梯度方法

    Tenengrad梯度方法利用Sobel算子分别计算水平和垂直方向的梯度,同一场景下梯度值越高,图像越清晰。以下是具体实现,这里衡量的指标是经过Sobel算子处理后的图像的平均灰度值,值越大,代表图像越清晰。

     

     

     
    1. #include <highgui/highgui.hpp>

    2. #include <imgproc/imgproc.hpp>

    3.  
    4. using namespace std;

    5. using namespace cv;

    6.  
    7. int main()

    8. {

    9. Mat imageSource = imread("2.jpg");

    10. Mat imageGrey;

    11.  
    12. cvtColor(imageSource, imageGrey, CV_RGB2GRAY);

    13. Mat imageSobel;

    14. Sobel(imageGrey, imageSobel, CV_16U, 1, 1);

    15.  
    16. //图像的平均灰度

    17. double meanValue = 0.0;

    18. meanValue = mean(imageSobel)[0];

    19.  
    20. //double to string

    21. stringstream meanValueStream;

    22. string meanValueString;

    23. meanValueStream << meanValue;

    24. meanValueStream >> meanValueString;

    25. meanValueString = "Articulation(Sobel Method): " + meanValueString;

    26. putText(imageSource, meanValueString, Point(20, 50), CV_FONT_HERSHEY_COMPLEX, 0.8, Scalar(255, 255, 25), 2);

    27. imshow("Articulation", imageSource);

    28. waitKey();

    29. }

     

     

    使用三张测试图片模拟不同对焦。第一张最清晰,得分最高,第二三张越来越模糊,得分依次降低。

     

     

     

     

    Laplacian梯度方法:

     

    Laplacian梯度是另一种求图像梯度的方法,在上例的OpenCV代码中直接替换Sobel算子即可。

     

     

     
    1. #include <highgui/highgui.hpp>

    2. #include <imgproc/imgproc.hpp>

    3.  
    4. using namespace std;

    5. using namespace cv;

    6.  
    7. int main()

    8. {

    9. Mat imageSource = imread("1.jpg");

    10. Mat imageGrey;

    11.  
    12. cvtColor(imageSource, imageGrey, CV_RGB2GRAY);

    13. Mat imageSobel;

    14.  
    15. Laplacian(imageGrey, imageSobel, CV_16U);

    16. //Sobel(imageGrey, imageSobel, CV_16U, 1, 1);

    17.  
    18. //图像的平均灰度

    19. double meanValue = 0.0;

    20. meanValue = mean(imageSobel)[0];

    21.  
    22. //double to string

    23. stringstream meanValueStream;

    24. string meanValueString;

    25. meanValueStream << meanValue;

    26. meanValueStream >> meanValueString;

    27. meanValueString = "Articulation(Laplacian Method): " + meanValueString;

    28. putText(imageSource, meanValueString, Point(20, 50), CV_FONT_HERSHEY_COMPLEX, 0.8, Scalar(255, 255, 25), 2);

    29. imshow("Articulation", imageSource);

    30. waitKey();

    31. }

     

    用同样的三张测试图片测试,结果一致,随着对焦模糊得分降低:

     

     

     

     

    方差方法:

     

    方差是概率论中用来考察一组离散数据和其期望(即数据的均值)之间的离散(偏离)成都的度量方法。方差较大,表示这一组数据之间的偏差就较大,组内的数据有的较大,有的较小,分布不均衡;方差较小,表示这一组数据之间的偏差较小,组内的数据之间分布平均,大小相近。

     

    对焦清晰的图像相比对焦模糊的图像,它的数据之间的灰度差异应该更大,即它的方差应该较大,可以通过图像灰度数据的方差来衡量图像的清晰度,方差越大,表示清晰度越好

     

     

     
    1. #include <highgui/highgui.hpp>

    2. #include <imgproc/imgproc.hpp>

    3.  
    4. using namespace std;

    5. using namespace cv;

    6.  
    7. int main()

    8. {

    9. Mat imageSource = imread("2.jpg");

    10. Mat imageGrey;

    11.  
    12. cvtColor(imageSource, imageGrey, CV_RGB2GRAY);

    13. Mat meanValueImage;

    14. Mat meanStdValueImage;

    15.  
    16. //求灰度图像的标准差

    17. meanStdDev(imageGrey, meanValueImage, meanStdValueImage);

    18. double meanValue = 0.0;

    19. meanValue = meanStdValueImage.at<double>(0, 0);

    20.  
    21. //double to string

    22. stringstream meanValueStream;

    23. string meanValueString;

    24. meanValueStream << meanValue*meanValue;

    25. meanValueStream >> meanValueString;

    26. meanValueString = "Articulation(Variance Method): " + meanValueString;

    27.  
    28. putText(imageSource, meanValueString, Point(20, 50), CV_FONT_HERSHEY_COMPLEX, 0.8, Scalar(255, 255, 25), 2);

    29. imshow("Articulation", imageSource);

    30. waitKey();

    31. }

     

     

    方差数值随着清晰度的降低逐渐降低:

     

     

     

    在工业应用中,最清晰的对焦拍摄出来的图像不一定是最好的,有可能出现摩尔纹(水波纹)现象,一般需要在最清晰对焦位置附件做一个微调。

    展开全文
  • 最近想实现相机自动对焦,也就是需要图像清晰度评价,在网上查找。 第一个不错文章是:无参考图像的清晰度评价方法 http://nkwavelet.blog.163.com/blog/static/227756038201461532247117 这个对理论或者公式介绍...

    最近想实现相机自动对焦,也就是需要图像清晰度评价,在网上查找。

    第一个不错文章是:无参考图像的清晰度评价方法

     http://nkwavelet.blog.163.com/blog/static/227756038201461532247117

    这个对理论或者公式介绍很详细,共有16个计算方法,值得一学。

    (1)Brenner 梯度函数

    (2)Tenengrad 梯度函数

    (3)Laplacian 梯度函数

    (4)SMD(灰度方差)函数

    ...

    后面是模糊检测,噪点检测,噪点和模糊的组合

    文章注重理论,没有具体的样例程序。有结果对比图。

    第二个不错文章是:OpenCV 图像清晰度评价(相机自动对焦)

    https://blog.csdn.net/dcrmg/article/details/53543341

    这个集中上面前三个方法的实现,这3个在opencv 都有函数实现。实现3种清晰度评价方法,分别是Tenengrad梯度方法、Laplacian梯度方法和方差方法。

    Tenengrad梯度方法,衡量的指标是经过Sobel算子处理后的图像的平均灰度值,值越大,代表图像越清晰。Sobel 函数。

    Laplacian梯度方法:同上,但用的是 Laplacian 函数

    方差方法:方差是概率论中用来考察一组离散数据和其期望(即数据的均值)之间的离散(偏离)程度的度量方法。方差较大,表示这一组数据之间的偏差就较大,组内的数据有的较大,有的较小,分布不均衡;方差较小,表示这一组数据之间的偏差较小,组内的数据之间分布平均,大小相近。方差越大,表示清晰度越好。

    这个有样例程序可参考。

    下面给出第一个算法的代码如下(第二个只是注销部分差异):

    #include <highgui/highgui.hpp>
    #include <imgproc/imgproc.hpp>
     
    using namespace std;
    using namespace cv;
     
    int main()
    {
    	Mat imageSource = imread("2.jpg");
    	Mat imageGrey;
     
    	cvtColor(imageSource, imageGrey, CV_RGB2GRAY);
    	Mat imageSobel;
    	Sobel(imageGrey, imageSobel, CV_16U, 1, 1);
      //Laplacian(imageGrey, imageSobel, CV_16U); 算法2
     
    	//图像的平均灰度
    	double meanValue = 0.0;
    	meanValue = mean(imageSobel)[0];
     
    	//double to string
    	stringstream meanValueStream;
    	string meanValueString;
    	meanValueStream << meanValue;
    	meanValueStream >> meanValueString;
    	meanValueString = "Articulation(Sobel Method): " + meanValueString;
    	putText(imageSource, meanValueString, Point(20, 50), CV_FONT_HERSHEY_COMPLEX, 0.8, Scalar(255, 255, 25), 2);
    	imshow("Articulation", imageSource);
    	waitKey();
    }

    这里的评估值就是 meanValue ,值越大越清晰。// double to string 部分只是加在图上显示。

    方差计算的差异是:

    //求灰度图像的标准差
    	meanStdDev(imageGrey, meanValueImage, meanStdValueImage);
    	double meanValue = 0.0;
    	meanValue = meanStdValueImage.at<double>(0, 0);

    文中也提到:

    在工业应用中,最清晰的对焦拍摄出来的图像不一定是最好的,有可能出现摩尔纹(水波纹)现象,一般需要在最清晰对焦位置附件做一个微调。 

     

     

    展开全文
  • OpenCV 图像清晰度评价(相机自动对焦) 相机的自动对焦要求相机根据拍摄环境和场景的变化,通过相机内部的微型驱动马达,自动调节相机镜头和CCD之间的距离,保证像平面正好投影到CCD的成像表面上。这时候物体的...
  • 最近在处理OpenCV进行图像识别时,需要连续的调焦(对焦),并在对焦完成后进行拍照,获取图片后进行图像识别。识别完成后摄像头不关闭继续进行扫描识别。整理成本文。 概念 焦距,也称为焦长,是光学系统中衡量光的...
  • 最近在处理OpenCV进行图像识别时,需要连续的调焦(对焦),并在对焦完成后进行拍照,获取图片后进行图像识别。识别完成后摄像头不关闭继续进行扫描识别。整理成本文。 概念 焦距,也称为焦长,是光学系统中衡量...
  • 相机的自动对焦要求相机根据拍摄环境和场景的变化,通过相机内部的微型驱动马达,自动调节相机镜头和CCD之间的距离,保证像平面正好投影到CCD的成像表面上。这时候物体的成像比较清晰,图像细节信息丰富。 相机自动...
  • 自动对焦 该项目是gPhoto2连接到OpenCV概念证明。 它是基于边缘检测的自动对焦的简单实现。 仅在尼康DSLR上进行了测试。 (尼康D90)。 但它可以在所有尼康数码单反相机上使用,并且与其他设备的工作几乎没有关系。 ...
  • opencv-4.2.0-vc14_vc15 图像卷积及其滤波 Definition:convolution、noise reduction/smoothing/coherence/incoherence。 用coherence的灰度值取代incoherence的灰度值 Tenengrad梯度方法 Tenengrad梯度方法利用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 507
精华内容 202
关键字:

opencv自动对焦