마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

카메라 영상 이진화 질문드립니다

0 추천
public void Binarization(final Camera mCamera)
{
    final Camera finalMCamera = mCamera;
    mCamera.setPreviewCallback(new Camera.PreviewCallback()
    {
        public void onPreviewFrame(byte[] data, Camera camera)
        {
            Camera.Parameters params = finalMCamera.getParameters();

            int w = params.getPreviewSize().width;
            int h = params.getPreviewSize().height;

            int format = params.getPreviewFormat();

            YuvImage image = new YuvImage(data, format, w, h, null);

            ByteArrayOutputStream out = new ByteArrayOutputStream();

            Rect area = new Rect(0, 0, w, h);

            image.compressToJpeg(area, 50, out);
            Bitmap Bit = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size()).copy(Bitmap.Config.ARGB_8888, true);

            for (int i = 0; i < data.length; i+=2)
            {
                if(i/Bit.getWidth() >= Bit.getHeight()) break;

                int pixel = Bit.getPixel(i % Bit.getWidth(), i / Bit.getWidth());
                int a = Color.alpha(pixel);
                int r = Color.red(pixel);
                int g = Color.green(pixel);
                int b = Color.blue(pixel);

                if (r >200 || b>200 || g>200)
                {
                    Bit.setPixel(i % Bit.getWidth(), i / Bit.getWidth(), 255);
                }

               else
                {
                    Bit.setPixel(i % Bit.getWidth(), i / Bit.getWidth(), 1);
                }
            }

            OutputStream outs = null;

            try
            {
                Matrix mat = new Matrix();
                mat.postRotate(90);
                Bit = Bit.createBitmap(Bit, 0, 0, Bit.getWidth(), Bit.getHeight(), mat, true);

                File file = new File(getApplicationContext().getFilesDir().getPath().toString(), "test.png");

                file.createNewFile();
                outs = new FileOutputStream(file);

                Bit.compress(Bitmap.CompressFormat.PNG, 100, outs);
                outs.close();
                
                Log.d("Tag", "release");
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
            catch (Exception e)
            {
                Toast.makeText(getApplicationContext(), "file error", Toast.LENGTH_LONG).show();
                Log.d("Tag", "error");
                e.printStackTrace();
            }
            finally
            {
                return;
            }
        }
    });
}
이게 코드구요
제 의도는 Bit라는 Bitmap객체가 현재 프레임을 가리키고 있고
이를  data배열에 접근합니다
제가 구글링을 해봤으나 data배열의 구조를 못찾아서
(0,0)    (0, 1)    (0, 2)    (1,0)    (1, 1)    (1, 2) ....
이런식으로 구조화 되어있을거라 예상하고 코딩했습니다.
그래서 for(int i=0; i < data.length; i+=2)    //실시간으로 해야되는데 i가 1씩 증가하니까 너무 느리더군요
이때 data의 가로길이는 Bit.getWidth로 나눈 나머지이고
data의 세로길이는 Bit.getWidth로 나눈 몫이니까 for문 안에는 저렇게 코딩한거구요
r g b 각각 200 이상으로 해놓은것은 테스트 후에 고쳐야 되는 부분이라 처음에는 임의값을 넣어두었습니다.

그리고  try부에서 파일을 저장하니까 이미지가 90도 돌아가있더군요(프리뷰에서 임의로 90도 돌려서 본거니 원래 이미지는 이게 맞는거겠죠)
그래서 Matrix를 이용해서 90도를 돌린거구요

==============================
여기까지가 코딩에 대한 설명이구
질문을 드리자면, 이진화가 안됩니다. 처음엔 rgb값이 아닌 getPixel을 이용해서 단순히 그 값이 128 이상이면 255 그 이하면 1로 세팅시켰지만
안되었으니 제가 가정한 상황이 틀렸다고 생각합니다.
이진화가 안되는 이유를 알려주시면 정말 감사하겠습니다.
익명사용자 님이 2017년 1월 23일 질문

1개의 답변

0 추천
 
채택된 답변
저도 100% 정확하지는 않으니 자체적으로 필터링해서 이해해 주세요.

제가 이해 하기로는 비트맵에서 1픽셀마다 Alpha, Red, Green, Blue 의 정보를 가지고 있고

각각 영역은 8비트씩 총 32비트로

 

질문자님께서 지정한 128, 255는 이진화를 하기에는 턱없이 적은 임계값이 아닌가 생각이 됩니다.

예전에 오픈소스에서 이미지 이진화 하는 코드를 본적이 있는데 각각 RGB 값을 추출해서 그 추출된 3가지의 색상의 평균을 가지고 이진화를 하는 코드를 보았었습니다. 코드가 있으면 공유해 드리고 싶은데 코드를 찾기가 힘드네요.

 

참고로 영상처리 같은경우 직접 구현하는거보다 OpenCV를 사용하는것이 차원적으로 다릅니다.
Development Guy (70,570 포인트) 님이 2017년 1월 23일 답변
...