Android Day03
by 木石溪
今天被實驗室大佬抓住,說我在不幹正事,讓寫個灰度直方圖均衡化的攝像Demo,
怎麼可能屈服在他淫威下,我寫還不行。。。慫~~
實現思路:
- Part1:調用攝像頭
1. 動態授權;
2. 設置拍照意圖,啓動拍照; - Part2:圖片處理
3. 進行圖像二值化;
4. 進行灰度直方圖均衡化;
5. 顯示處理圖片;
step1:界面(按鍵 + 均衡化顯示)
主要部件:
- 拍照 Button
- 圖片顯示 ImageView
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:ignore="TableFor" tools:context=".MainActivity"> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:id="@+id/bt_camera" android:text="@string/bt_camera" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="@+id/imageView" android:layout_marginBottom="3dp" app:layout_constraintBottom_toTopOf="@+id/imageView"/> <ImageView android:layout_width="0dp" android:layout_height="0dp" android:id="@+id/imageView" app:layout_constraintTop_toBottomOf="@+id/bt_camera" android:layout_marginBottom="2dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> </android.support.constraint.ConstraintLayout>
Step2:實現攝像頭動態授權和調用
Part01 : 設置按鍵監聽
// load layout and find view parts by id setContentView(R.layout.activity_main); Button bt_camera = findViewById(R.id.bt_camera); mMImageView = findViewById(R.id.imageView); // set listener of button clicked bt_camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSION_REQUEST_CODE); } else { takePhoto(); } } });
Part02: 進行M 運行權限授權
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case MY_PERMISSION_REQUEST_CODE: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { takePhoto(); } else { Toast.makeText(this, "THE PERMISSION DENIED", Toast.LENGTH_SHORT).show(); } default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } }
Part03:設置拍照程序
private void takePhoto() { Intent photo_act = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(photo_act, TAKE_PHOTO_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case TAKE_PHOTO_CODE: Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); // digital image processing Bitmap dst = equalize(imageBitmap); mImageView.setImageBitmap(dst); break; default: break; } } }
Part04: 圖像二值化和直方圖均衡化處理
//-------------------------------------- // Digital Image Processing //-------------------------------------- private Bitmap equalize(Bitmap src){ // 1. convert Bitmap to color array int rows = src.getHeight(); int cols = src.getWidth(); int size = rows * cols; int[] img = new int[rows * cols]; // each element of color array is a PACKED color code for that pixel, which can be decomposed to A,R,G and B src.getPixels(img,0,cols,0,0,cols,rows); // 2. convert ARGB/RGB color code 2 Gray Scale and calculate image histogram // since we've already allocated a int array for all the pixels, there's no need to allocated another 'uchar' for them int base,id,color,level,r,c = 0; int[] hist = new int[256]; for(r=0; r<rows; r++){ base = r*cols; for(c=0; c<cols; c++){ id = base + c; color = img[id]; level = (int)Math.round((0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color))); img[id] = level; // calculate histogram at the same time hist[level]++; } } // 3. get PDF double[] pdf = new double[256]; for(int i=0; i<256; i++){ pdf[i] = (double)hist[i]/size; } // 4. get CDF and generate dictionary int[] dict = new int[256]; double tmpd = 0; for(int m=0; m<256; m++){ tmpd = 0; for(int n=0; n<=m; n++){ tmpd += pdf[n]; } dict[m] = (int)Math.round(255*tmpd); } // 5. map img back to color code using dictionary for(r=0; r<rows; r++){ base = r*cols; for(c=0; c<cols; c++){ id = base + c; level = dict[img[id]]; img[id] = Color.rgb(level,level,level); } } System.out.println(dict[200] + ", " + dict[201] + ", " + dict[202]); System.out.println(img[200] + ", " + img[201] + ", " + img[202]); // 6. set Bitmap return Bitmap.createBitmap(img,cols,rows,src.getConfig()); }
結果:
未解決問題
- 目前處理圖片爲略縮圖,圖像清晰度不夠;
- 灰度直方圖均衡化算法有待提升;