DeathMark: 프로그래밍 방식으로 비디오에서 관심 지점 검색

문제



2020년에 대부분의 사람들처럼 우리 회사는 더 많은 원격 근무로 전환했고 저는 다가오는 확대/축소 회의에 대비하기 위해 홈 오피스에 투자하기 시작했습니다. 일단 편안한 설정을 하고 나면 직장 밖에서도 스트리밍을 시작하는 데 필요한 모든 것을 갖추었습니다. 나는 twitch로 놀기 시작했고 YouTube 용으로 비디오를 자르기 시작했습니다.

내 스트림의 대부분은 2시간 이상이었고 친구들과 2시간 이상 게임을 하는 동안 휴식과 우정에 투자했습니다. 2시간 이상을 다시 보는 것은 내가 하고 싶었던 시간 투자가 아니었습니다.

임신



내가 선택한 게임은 현재 Valorant이지만 이것은 대부분의 게임에 해당됩니다. 게임에는 점수를 획득했음을 보여주는 시각적 대기열이 있습니다.



그것들은 UI 요소이기 때문에 일반적으로 시각적으로 밝고 일관되게 배치되며 게임의 배경 보기와 구별됩니다.

점수 표시기는 깜박이는 불빛과 같습니다. Light-Dependent Resistor와 같은 것이 있으면 깜박일 때 기록할 수 있습니다.



신청



나는 "비디오에서 흰색 증가를 확인하십시오"라는 개념을 가지고 있습니다.
MDN에는 HTML 캔버스를 사용하여 비디오의 각 프레임을 확인하는 방법에 대한 좋은 예가 있습니다. 예제는 다음과 같이 설정됩니다.


ctx1 = 캔버스 1 컨텍스트
ctx2 = 캔버스 2 컨텍스트

우리는 그들의 기능을 빌리고 computeFrame 섹션에 초점을 맞출 것입니다. 아래에서 각 프레임의 각 픽셀에 대한 RGB 값을 볼 수 있습니다.

 processor.computeFrame = function computeFrame() {
//drawing the full frame to canvas
    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
//get the frame from canvas at 0 x and 0 y 
    let frame = this.ctx1.getImageData(0, 0, this.width, this.height);

    let l = frame.data.length / 4;

    for (let i = 0; i < l; i++) {
      let r = frame.data[i * 4 + 0];
      let g = frame.data[i * 4 + 1];
      let b = frame.data[i * 4 + 2];
      if (g > 100 && r > 100 && b < 43)
        frame.data[i * 4 + 3] = 0;
    }
    this.ctx2.putImageData(frame, 0, 0);
    return;
  }


위의 예에서는 이 색상 범위를 확인하고 임계값 내에 있으면 알파로 변경하여 녹색 화면 또는 이 경우 노란색 화면을 생성합니다.


충분히 간단합니다. 해당 영역의 흰색 픽셀만 확인하겠습니다.

//255,255,255 is white so 240 -> 255 is mostly white
 if (g > 240 && r > 240 && b < 240)
        //is white pixel
    }


하지만 이 게임은 시각적으로 복잡하고 많은 요소가 "흰색"만 트리거합니다.



모든 사진은 거의 고유한 양의 색상과 음영으로 구성되어 있으므로 해당 고유 번호에 최대한 가까워지기만 하면 됩니다.



let skullFound = []
let white = []
let green = []
let red = []
for (let i = 0; i < l; i++) {
      let r = frame.data[i * 4 + 0];
      let g = frame.data[i * 4 + 1];
      let b = frame.data[i * 4 + 2];
       if (isWhite(r,g,b))
         white.push({r,g,b})
       }
      if (isGreen(r,g,b))
        green.push({r,g,b})
      }
      if (isRed(r,g,b))
        red.push({r,g,b})
      }
}

if(whiteThreshold(white.length) && greenThreshold(green.length) && redThreshold(red.length)) {
 skullFound.push(video.currentTime)
 white = []
 green = []
 red = []
}


30분의 시행 착오 끝에 저격 소총으로 총을 맞았을 때 Character Sage가 잘린 부분 내에 있는 경우 1가지 주요 예외를 제외하고 테스트한 동영상으로 2배속에서 약 99%의 정확도를 얻을 수 있었습니다. .. 좀 드문 일입니다.



결론



현재 시스템이 완벽하지는 않지만 나중에 구축할 수 있는 내가 직면한 문제에 대한 단순한 솔루션입니다.

위와 같은 방법은 많은 게임 영상에 적용될 수 있다고 생각합니다. 앞으로 이 분야에서 더 재미있는 기술을 찾을 수 있기를 기대합니다.

무료 다운로드



https://ko-fi.com/post/DeathMark-W7W8381IO

좋은 웹페이지 즐겨찾기