Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VIEWER-167] Heatmap Viewer 스펙 변경 #422

Merged
merged 10 commits into from
Oct 31, 2024
83 changes: 78 additions & 5 deletions libs/insight-viewer/src/utils/HeatmapViewer/getHeatmapImageData.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/* eslint-disable prefer-destructuring */
/* eslint-disable one-var */
/* eslint-disable no-param-reassign */
/* eslint-disable no-bitwise */
import { getRGBArray } from './getRGBArray'

interface GetHeatmapImageDataProps {
Expand Down Expand Up @@ -53,10 +49,87 @@ export default function getHeatmapImageData({
pixels[offset] = pixVal[0]
pixels[offset + 1] = pixVal[1]
pixels[offset + 2] = pixVal[2]
pixels[offset + 3] = (thPosProb * 196) << 0
pixels[offset + 3] = Math.round(255 * 0.35)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반복문 내에서 사용되는 값이니 상수 사용하는 것이 좋겠습니다

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수로 선언 후 사용하는 방식으로 수정했습니다. 817ea51

}
}

// Apply Gaussian blur
applyGaussianBlur(pixels, heatmapWidth, heatmapHeight, 1)

return { heatmapData: heatmapImageData, heatmapCanvas }
}

function applyGaussianBlur(pixels: Uint8ClampedArray, width: number, height: number, sigma: number) {
const kernel = generateGaussianKernel(sigma)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

직접 구현하기보다는 blur() 필터를 사용하는게 좋을 것 같습니다
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀해주신 것처럼 직접 구현한 로직 삭제 후, blur 방식을 적용했습니다. b831f8f

blur 를 적용한 기준 디자인은 디자인팀에 검수까지 받은 상태입니다.

const tempPixels = new Uint8ClampedArray(pixels.length)

for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
applyKernel(pixels, tempPixels, x, y, width, height, kernel, true)
}
}

for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
applyKernel(tempPixels, pixels, x, y, width, height, kernel, false)
}
}
}

function generateGaussianKernel(sigma: number): number[] {
const kernelSize = Math.ceil(sigma * 6) + 1
const kernel = new Array(kernelSize).fill(0)
const center = Math.floor(kernelSize / 2)

let sum = 0
for (let i = 0; i < kernelSize; i++) {
const x = i - center
kernel[i] = Math.exp(-(x * x) / (2 * sigma * sigma))
sum += kernel[i]
}

// 정규화
for (let i = 0; i < kernelSize; i++) {
kernel[i] /= sum
}

return kernel
}

function applyKernel(
src: Uint8ClampedArray,
dst: Uint8ClampedArray,
x: number,
y: number,
width: number,
height: number,
kernel: number[],
horizontal: boolean
) {
const center = Math.floor(kernel.length / 2)
let r = 0,
g = 0,
b = 0,
a = 0

for (let i = 0; i < kernel.length; i++) {
const ki = kernel[i]
const xi = horizontal ? x + i - center : x
const yi = horizontal ? y : y + i - center

if (xi >= 0 && xi < width && yi >= 0 && yi < height) {
const offset = (yi * width + xi) * 4
r += src[offset] * ki
g += src[offset + 1] * ki
b += src[offset + 2] * ki
a += src[offset + 3] * ki
}
}

const offset = (y * width + x) * 4
dst[offset] = r
dst[offset + 1] = g
dst[offset + 2] = b
dst[offset + 3] = a
}
33 changes: 18 additions & 15 deletions libs/insight-viewer/src/utils/HeatmapViewer/getRGBArray.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
/* eslint-disable no-bitwise */

/**
* A function that converts probability values
* (0~1) of a specific area into [r, g, b] arrays corresponding to JET colormap colors
*/
export function getRGBArray(value: number): number[] {
let r = 1.0
let g = 1.0
let b = 1.0
const v = Math.max(Math.min(value, 1), 0)
let r, g, b

if (v < 0.25) {
r = 0
g = 4 * v
// Between 0 and 0.25: 74,230,255 fixed
r = 74
g = 230
b = 255
} else if (v < 0.5) {
r = 0
b = 1 + 4 * (0.25 - v)
} else if (v < 0.75) {
r = 4 * (v - 0.5)
b = 0
// Between 0.25 and 0.5: linearly convert from 74,230,255 to 221,255,0
const t = (v - 0.25) / 0.25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

괄호를 넣어줘야 rbg임을 쉽게 알 수 있을 것 같습니다

Suggested change
// Between 0.25 and 0.5: linearly convert from 74,230,255 to 221,255,0
// Between 0.25 and 0.5: linearly convert from (74,230,255) to (221,255,0)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀해주신 것처럼 괄호를 추가했습니다. 1160997

r = Math.round(74 + t * (221 - 74))
g = Math.round(230 + t * (255 - 230))
b = Math.round(255 + t * (0 - 255))
} else {
g = 1 + 4 * (0.75 - v)
b = 0
// 0.5 to 1 interval: linearly convert from 221,255,0 to 255,0,92
const t = (v - 0.5) / 0.5
r = Math.round(221 + t * (255 - 221))
g = Math.round(255 + t * (0 - 255))
b = Math.round(0 + t * (92 - 0))
}
return [(r * 255) << 0, (g * 255) << 0, (b * 255) << 0]

return [r, g, b]
}
Loading