일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- tensorflow update
- Convolution Neural Network
- findContours
- word embedding
- tokenizing
- #Android
- c언어
- object detection
- #일상영어
- #실생활 영어
- #opencv
- 영어명언
- #1일1영어
- #실생활영어
- python __init__
- 딥러닝
- #영어
- 이미지 생성
- #영어 명언
- keras
- convexhull
- python 알고리즘
- 영어
- 완전탐색
- #프로젝트
- python list
- TensorFlow
- #English
- opencv SURF
- text2img
- Today
- Total
When will you grow up?
4. BitPlane 함수 만들기(Bit-Plane Slicing) 본문
4. BitPlane 함수 만들기(Bit-Plane Slicing)
미카이 2016. 9. 17. 15:03이번에는 비트플레인 함수를 만들겠습니다
BitPlane 이란?
디지털 정보 용어로써, 우리말로는 비트 평면이라고 얘기를 한다.
8bit 그레이 영상의 한 픽셀은 8개의 bit로 구성됩니다^^
즉, 픽셀값은 00000000(0)~11111111(255)까지의 값을 가질 수 있죠
8개의 bit중에서 최상위 비트를 MSB(Most Significant Bit), 최하위 비트를 LSB(Least Significant Bit)라고 합니다
위의 표는 이진수를 간단히 십진수로 변환할 수 있는 방법입니다..^^
특히 4bit짜리는 8-4-2-1 코드로 잘 알려져 있죠..^^
예를들어, 이진수 0110은 8과 1의 값은 0이고, 4와 2의 값은 1이기 때문에 4 + 2 = 6이 됩니다^^
이진수 '1100 0000'값은 128 + 64 = 192가 되는거죠..^^
사실 이런 변환 방법이 중요한게 아니라, 상위 비트로 갈수록 값이 커진다는 것이 핵심입니다
쉽게 말하자면, 최상위 비트는 가장 큰 값이므로 가장 중요하다 (Most Significant)
최하위 비트는 가장 작은 값이므로 가장 중요하지 않다 (Least Significant)가 되는 것이죠..^^
0~255의 범위를 놓고 봤을때, 예를 들자면..
'0001 0100'(20)과 '0001 0101'(21)의 최하위 1비트는 1차이가 나므로 별로 중요하지 않다는 것이죠^^
하지만 '0001 0100'(20)과 '1001 0100'(148)은 128차이가 나버립니다..
영상의 픽셀값으로 치자면 거의 검은색(20)과 중간보다 밝은 회색(148)이 되어버리는 거죠..^^;
이런 차이는 사람눈으로도 쉽게 구별할 수 있을만큼 확연한 차이입니다
실제로 색을 비교해볼까요?^^
픽셀값 20()과 21()은 거의 구분이 불가능하지만,
픽셀값 20()과 148()은 확연한 차이를 보입니다..^^
둘 다 똑같이 한 비트의 값만 달라졌는데도 완전히 다른 결과를 보입니다^^
값이 바뀌어도 원본과 큰 차이가 없기 때문에 별로 신경쓸 필요없는 (즉, 중요하지 않은)
하위 몇 비트 정도는 잘라내 버려도 상관없다는 것이 바로 절단 부호화의 포인트인 것이죠..^^
하위 4bit정도를 잘라내버려도 최대 1111(15)정도의 손실밖에 없으며,
사람눈으로 볼 때는 영상을 알아보는데 별 문제가 없습니다 (물론, 화질의 손상은 있습니다만..)
대신 데이터 양은 절반으로 줄어들게 되는 것이죠..^^
반면 상위 4bit를 잘라버리면 최대 11110000(240)의 손실이 발생합니다..
8bit 그레이 영상의 픽셀값이 0~255사이의 값을 갖는데..
원본과 240이 차이가 난다면, 그건 원본 데이터와는 아예 달라져버리는 것이죠..^^;;
-출처 : http://egloos.zum.com/realheart/v/2254010 (하얀추억 블로그) 위 내용 문제가 되면 바로 지우겠습니다.
핵심 함수는 이래와 같습니다.
void getBitPlane(Mat &srcImg, Mat &dstImg, int n)//(원본이미지 , bitplane될 이미지,n칸
{
uchar mask = 0x01 << n; //쉬프트연산자를 이용하여 n칸 밀어버림니다. 나머지 밀 //어져 버린 부분은 0으로 숫자가 초기화 됨니다.
Mat_<uchar> s = Mat_<uchar>(srcImg);
Mat_<uchar> d = Mat_<uchar>(dstImg);
/*for (int r = 0; r < srcImg.rows; r++)
{
for (int c = 0; c < srcImg.cols; c++)
{
uchar pixelvalue = s(r, c);
uchar onezero = pixelvalue & mask;
if (onezero > 0) d(r, c) = 255;
else d(r, c) = 0;
}
}*/
for (int r = 0; r < srcImg.rows; r++)
{
uchar *p = srcImg.ptr<uchar>(r);//첫번째행의 값을 가져온다.
uchar *dp = dstImg.ptr<uchar>(r);
for (int c = 0; c < srcImg.cols; c++)
{
uchar pixelvalue = p[c];
uchar one_zero = pixelvalue & mask;
if (one_zero > 0)
dp[c] = 255;
else
dp[c] = 0;
//dp[c] = one_zero ? 255 : 0;
}
}
}
하나는 주석처리 되어있는 부분을 주석을 푸시고 아래꺼 for문을 주석처리하셔도 같은 결과가 나옴니다.
원본 이미지
단계별로 bitplane 된 이미지 0~7
전체 소스코드는 아래와 같습니다.
#include "ofApp.h" const int width = 720; const int height = 480; unsigned char pixel[width*height * 3]; ofImage img, result; ofImage photo; Mat srcImg; Mat bitPlane[8]; void getBitPlane(Mat &srcImg, Mat &dstImg, int n) { uchar mask = 0x01 << n; Mat_s = Mat_ (srcImg); Mat_ d = Mat_ (dstImg); /*for (int r = 0; r < srcImg.rows; r++) { for (int c = 0; c < srcImg.cols; c++) { uchar pixelvalue = s(r, c); uchar onezero = pixelvalue & mask; if (onezero > 0) d(r, c) = 255; else d(r, c) = 0; } }*/ for (int r = 0; r < srcImg.rows; r++) { uchar *p = srcImg.ptr (r);//첫번째행의 값을 가져온다. uchar *dp = dstImg.ptr (r); for (int c = 0; c < srcImg.cols; c++) { uchar pixelvalue = p[c]; uchar one_zero = pixelvalue & mask; if (one_zero > 0) dp[c] = 255; else dp[c] = 0; //dp[c] = one_zero ? 255 : 0; } } } //-------------------------------------------------------------- void ofApp::setup() { photo.load("myimage2.jpg"); srcImg = Mat(photo.getHeight(),photo.getWidth(),CV_8UC3,photo.getPixels().getData()); Mat grayImg; cvtColor(srcImg, grayImg, COLOR_RGB2GRAY); cv::imshow("grayImage", grayImg); for (int i = 0; i < 8; i++) { bitPlane[i] = grayImg.clone(); getBitPlane(grayImg, bitPlane[i], i); string name = "bitplane" + std::to_string(i); cv::imshow(name, bitPlane[i]); } }
'02. Study > Computer Vision(openframworks&opencv)' 카테고리의 다른 글
6. LUT를 이용한 속도 비교(ColorReduction / ColorReductionLUT) (0) | 2016.09.17 |
---|---|
5. ColorReduction 만들기. (0) | 2016.09.17 |
3.blur()를 이용해 이미지 처리후 이미지 키보드 버튼을 이용해 이미지 저장. (2) | 2016.09.10 |
2.visualstdio2015에서 opencv+openframeworks 개발환경 구축 (22) | 2016.09.08 |
1_2.ofImage로 이미지를 띄워 이미지 Negative 시키기 (0) | 2016.09.08 |