Code Signal -Arcade
코드시그널
아케이드 문제 관련 풀이들을 구글링하면서 찾아가는 일지를 하나씩하나씩 기록하고자 합니당.
주로 자바 위주로 풀이를 올릴예정이고, 추가로 공부하고 있는 파이썬이나 코틀린, GO, 자바스크립트 더 나아가 스위프트까지...
되는대로 가능한대로 구글링하고 정답맞추면 바로 패스!!
이런식으로 좋은 코드이든 말든 짜집기한 결과물들을 개인적 소장을 위해 기록합니다. ^^
참고 사이트들은 아래에 링크로 남겨둘터이니 자세하고 더욱 깊은 내용들은 링크로 들어가보세요!
Box Blur
상자의 블러 처리.
문제를 보면, 이래저래 문제가 생겨서 어떠한 사진의 블러처리를 해야한다는 그런 내용..
아무튼 그 모자이크 처리를 위한 알고리즘을 만들어라..
사진은 픽셀로 구성되어 있는데, 그 픽셀의 원리는 다중배열과 비슷하다.
그러므로 어느 정사각형 정해진 비율의 사진(3x3)이 있을때, 그 비율에서 어떠한 특정부분을 블러 처리를 한다.
잘 이해가 안갑니다. 예시를 바로 볼께요.
주어진대로 다중비율이 정사각? 구조로 되어있습니다.
여기서 to get the value of the middle pixel in the input square 의 계산을 보면,
(3x3) 범위에 들어가는 다중배열의 요소값들을 다 더해준뒤, 배열요소의 3*3인 9로 나누고..
그것으로 나눠준 값을 내림하여 값을 구해주고 그 값을 또 다중배열에 넣어주어야 합니다.
대략적으로 이해가 되셨다면 답안을 언제나 그랬듯 보겠습니다.
int[][] boxBlur(int[][] image) {
int x = image[0].length -2 ; // 열
int y = image.length -2 ; // 행
int [] [] b = new int [y][];
for(int i =0; i< y ; i++){
b[i] = new int [x];
for(int j =0; j< x; j ++){
b[i][j] = image[i][j] + image[i][j+1] + image[i][j+2]+
image[i+1][j] + image[i+1][j+1] + image[i+1][j+2]+
image[i+2][j] + image[i+2][j+1] + image[i+2][j+2];
b[i][j] /= 9;
}
}
return b;
}
어느정도 이해가 되시려나 모르겠습니다. 전 제가 해놓고도 잘 모르겠거든요.
의식의 흐름 수듄.
박스블러 알고리즘은 화질을 다운 시키는 방법이라고 생각하는데요. 일정하게 분배되어있는? 픽셀값을
동일한 비례값으로 떨어트립니다. 그렇게 되면 이미지의 화질이 다운되겠죠?
여기서 화질을 낮추는 방법은 일단 legnth의 최소값이 3이라는 점. 그래서 한단계 화질을 낮추는 방법은 -2를 시켜서
이미지의 질을 낮추는 방법입니다.
그리고 -2만큼 작아진 이미지 사이즈에는 그 교집합 부분들이 이미지의 크기로 정해집니다.
바로 그 부분의 이미지들은 기존의 컸던 이미지들의 압축형태처럼 되기 때문에 기존 사이즈의 값들이 다 합쳐져서
/9를 시켜주어 비례하게 들어가게 해줍니다.
대략적으로 뭔가 있는듯한 알고리즘입니다만,,,
https://en.wikipedia.org/wiki/Box_blur
전 걍 이해가 안되서 그냥 풀었어요..
어떻게 배열길이를 다 -2시켜야 했냐하면, test의 Expected Output을 통해서 감을 잡은 것 같습니다.
모든 배열들이 열/행 이 다 -2씩 줄어 있더군요.
그래서 그런 그릇을 만들어 줬습니다.
길이들은 다 -2 적용을 해주구요.
int x = image[0].length -2 ; // 열
int y = image.length -2 ; // 행
int [] [] b = new int [y][]; // -2가 적용된 다중배열
이렇게 된 상태로
반복문을 통해서
예시와 같은 공식을 넣어주려 했지만,,, 역시나 어렵더군용.. 저한테는..
3 x 3 범위에 있는 값들만 따로 빼서 더해줘야하는데, 골치가 아팠기에.
수동으로 돌리는 방법을 선택했습니다... 그결과 가 아래와 같죠.
for(int i =0; i< y ; i++){
b[i] = new int [x];
for(int j =0; j< x; j ++){
b[i][j] = image[i][j] + image[i][j+1] + image[i][j+2]+
image[i+1][j] + image[i+1][j+1] + image[i+1][j+2]+
image[i+2][j] + image[i+2][j+1] + image[i+2][j+2];
b[i][j] /= 9;
}
}
반복문 안에 또 반복을 넣어서 돌린겁니다.
b[i] = new int [x]; 이부분은 처음에 b를 선언해줄때, 열 부분을 설정을 안해줬기 때문에 해주는 것인데,
b[i] 상태로 선언을 해줍니다. 어차피 y는 선언이 되어있고 범위도 설정되어 있어서 상관없습니다.
그 후, 설정된 b 의 범위안에 3 * 3 사이즈들의 값을 넣어주고 각 각 /9를 해줘야 합니다.
이말이 무슨 말인지 잘 이해가 안되실 겁니다.. (저도 그랬어요)
그림으로 보여드릴께요.. (저도 다시 기억을 떠올려서 하는 중이라 복습이 되긴하네요 확실히..)
일단 이 테스트 4를 보면은 4 * 4 사이즈 짜리 이미지 픽셀 값들이 있습니다.
이것을 각 행과 열의 길이에 -2를 해주면 2 * 2 가 되겠죠?
그 원리가 뭐냐면,
이런개념입니다. 그림인 난잡한데요..;;;
큰 네모 안에, 각 색깔별로 구분이 되어있는 부분을 보실까요.
각 각 3 * 3 의 정사각형으로 구분되어있습니다.
이미지를 블러 처리하는 것은 바로 저렇게 3*3으로 이미지를 줄인다고 했을때,
저런식으로 분할하여
가장 중앙의 x구역에 줄어든 값을 넣어주는 겁니다.
이 그림을 봤을때, 저 화살표를 보시면, 저 노란색 원 의 구간이 box blur algorithm 이 적용된 후의 픽셀 공간입니다.
이해가 되시나요???
아무튼 이러한 개념으로 어떤식으로 계산이 진행되야하는지 보여주면,
이렇게 각각 3* 3의 방식의 계산이 진행되고, 그것들의 값은 저 위에 노란색 원에 있는
2 * 2 배열에 한 값씩 들어가게 해주는 겁니다. 그것을 나타낸 반복문이 바로
for(int i =0; i< y ; i++){
b[i] = new int [x];
for(int j =0; j< x; j ++){
b[i][j] = image[i][j] + image[i][j+1] + image[i][j+2]+
image[i+1][j] + image[i+1][j+1] + image[i+1][j+2]+
image[i+2][j] + image[i+2][j+1] + image[i+2][j+2];
b[i][j] /= 9;
}
}
이부분에 해당하는 것이죠. 좀 이해가 될겁니다. ㅎㅎ 아무튼! 이런 원리로 진행된 계산식이고 자연스럽게 리턴은 b 를 해주면 스무스하게 끝입니다.
다른 답지들을 보여드릴께요.
JAVA
int[][] boxBlur(int[][] image) {
int[][] result = new int[image.length-2][image[0].length-2];
for (int i = 1; i < image.length-1; i++) {
for (int j = 1; j < image[i].length-1; j++) {
result[i-1][j-1] = avg(image, i, j);
}
}
return result;
}
int avg(int[][] image, int x, int y) {
int sum = 0;
for (int i = x-1; i <= x+1; i++) {
for (int j = y-1; j <= y+1; j++) {
sum += image[i][j];
}
}
return sum / 9;
}
JS
boxBlur = I => {
//Slice off the border
var B = I.slice(1,-1).map(e=>e.slice(1,-1))
//Replace every element with the average
// of its neighbors
return B.map((row,i) =>
row.map((elem,j) => {
var sum = 0
for(var x=0;x<3;++x)
for(var y=0;y<3;++y)
sum += I[i+x][j+y]
return sum/9|0
})
)
}
PYTHON 3
def boxBlur(image):
return [[sum(sum(x[i:i+3]) for x in image[j:j+3])/9
for i in range(len(image[0])-2)]
for j in range(len(image)-2)]
파이썬은 무슨 저리 짧은지... 참 더 극혐이네요. 파이썬 공부 빨리해야겠다 싶습니다. ^^;;;; 열심히하자...;
'Algorithm > Java' 카테고리의 다른 글
#24_Code Signal Arcade >> Mine Sweeper (0) | 2019.11.27 |
---|---|
#22_Code Signal Arcade >> Avoid Obstacles (0) | 2019.11.25 |
#21_Code Signal Arcade >> Is IPv4 Address (0) | 2019.11.23 |