누군가가 올바른 방향으로 나를 가리킬 수 있는지 궁금 해서요. 이미지에서 텍스트를 더 쉽게 읽을 수 있도록 자바 스크립트를 사용하여 전화 카메라에서 가져온 이미지의 밝기/대비를 자동 조정합니다.밝기/대비를 자동 조정하여 이미지에서 텍스트를 읽습니다.
감사의 말 :
감사합니다.
누군가가 올바른 방향으로 나를 가리킬 수 있는지 궁금 해서요. 이미지에서 텍스트를 더 쉽게 읽을 수 있도록 자바 스크립트를 사용하여 전화 카메라에서 가져온 이미지의 밝기/대비를 자동 조정합니다.밝기/대비를 자동 조정하여 이미지에서 텍스트를 읽습니다.
감사의 말 :
감사합니다.
이미지를 자동으로 조정하려면 이미지에서 생성 한 막대 그래프를 사용하고 임계 값을 사용하여 픽셀 값을 반대쪽 끝의 최대 값으로 조정하는 데 사용할 흑백 포인트를 찾습니다.
HTML5에서 픽셀 정보를 읽으려면 canvas 요소를 사용해야합니다. 히스토그램
에게 히스토그램을 구축
예 루마 히스토그램
산출하는 휘도 값은 우리 REC.709 (여기서 사용 AKA 추천 BT.709,) 또는 REC.601 수식을 사용할 수있다.
Y = 0.299 * R + 0.587 * G + 0.114 * B
우리는 달리 우리 수납 정수 값을 [0, 255] (아래 예 코드 참조)에 기초하여 상기 히스토그램을 구축 힘든 시간을받는 것, 정수 (iluma = Math.round(luma);
)이 변환 할 필요가있다.
사용할 범위를 결정하는 전략은 다양 할 수 있지만 간단히하기 위해 양 끝의 최소 픽셀 표현을 기반으로 임계 값 전략을 선택할 수 있습니다.
레드 라인을 보여주는 예 임계 값
우리가 왼쪽에서 오른쪽으로 스캔 할 임계 값을 기반으로 어두운을 찾으려면 우리가 임계 사용과 같은 최소값 위의 루마 값을 얻을 때. 우리가 중심에 도달하면 (또는 33 % 만) 0과 기본값을 맞출 수 있습니다.
가장 밝은 값은 오른쪽에서 왼쪽으로 255를 기본값으로 사용합니다. 임계 값이없는 경우 기본값으로 255로 설정됩니다.
물론 각 끝마다 서로 다른 임계 값을 사용할 수 있습니다. 시나리오에 맞는 것을 찾을 때까지 모든 값의 시행 착오입니다.
이제 우리는 최소 - 최대 범위를 나타내는 두 개의 값을 가져야한다 : 임계치에 기초
최소 - 최대 범위를 일반적인 휘도 레벨
먼저 스케일을 계산하는 스케일링
scale = 255/(max - min) * 2
클립을 의미하는 경우에도 각 구성 요소에서 분을 뺍니다 (< 0이 값을 0으로 설정 한 경우). 뺄 때 우리는 축척 계수를 사용하여 각 구성 요소 값을 축척합니다. 끝의 x2는 루마와 실제 RGB 값 사이의 차이를 보정하는 것입니다. 다른 사람들처럼이 값으로 놀아 라.
우리는 각 화소의 각 성분 (0 클립 스케일)이 작업을 수행 화상 데이터가 소정의 임계 값에 기초하여 최대되어야 콘트라스트를 다시 넣어
component = max(0, component - min) * scale
.
당신은 히스토그램을 분석하기 위해 전체 이미지 비트 맵을 사용할 필요가 없습니다. 큰 이미지 소스를 다루는 경우 작은 표현으로 축소 할 수 있습니다. 가장 밝거나 가장 어두운 영역 다음에 단일 픽셀이 아닌만큼 많이 필요하지는 않습니다.
넌 밝게 및 multiply
, lighten
으로 자기 블렌딩 모드를 이용하여 명암 화상을 추가/soft-light
hard-light
등 (< = IE11 블렌딩 모드를 지원하지 않음). 이 수식을 조정하고 실험하십시오.
이것은 위에서 설명한 기술을 보여주는 버퍼에서 작동합니다. 더 복잡하고 정확한 방법이 있지만 이것은 개념 증명 (CC-3.0-by-sa, attribution required으로 라이센스)으로 주어집니다.
10 %의 임계 값부터 시작합니다. 임계 값을 사용하여 결과의 차이를 보려면 슬라이더를 사용하십시오. 임계 값은 여기에 표시된 것 이외의 다른 방법을 통해 계산 될 수 있습니다. 실험! 전체 페이지를 사용하여
실행 조각 -
var ctx = c.getContext("2d"),
img = new Image; // some demo image
img.crossOrigin =""; // needed for demo
img.onload = setup;
img.src = "//i.imgur.com/VtNwHbU.jpg";
function setup() {
// set canvas size based on image
c.width = this.width;
c.height = this.height;
\t
// draw in image to canvas
ctx.drawImage(this, 0, 0);
// keep the original for comparsion and for demo
org.src = c.toDataURL();
process(this, +tv.value);
}
function process(img, thold) { //thold = % of hist max
var width = img.width, height = img.height,
idata, data,
i, min = -1, max = -1, // to find min-max
maxH = 0, // to find scale of histogram
scale,
hgram = new Uint32Array(width); // histogram buffer (or use Float32)
\t
// get image data
idata = ctx.getImageData(0, 0, img.width, img.height); // needed for later
data = idata.data; // the bitmap itself
\t
// get lumas and build histogram
for(i = 0; i < data.length; i += 4) {
var luma = Math.round(rgb2luma(data, i));
hgram[luma]++; // add to the luma bar (and why we need an integer)
}
\t
// find tallest bar so we can use that to scale threshold
for(i = 0; i < width; i++) {
if (hgram[i] > maxH) maxH = hgram[i];
}
// use that for threshold
thold *= maxH;
\t
// find min value
for(i = 0; i < width * 0.5; i++) {
if (hgram[i] > thold) {
min = i;
break;
}
}
if (min < 0) min = 0; // not found, set to default 0
// find max value
for(i = width - 1; i > width * 0.5; i--) {
if (hgram[i] > thold) {
max = i;
break;
}
}
if (max < 0) max = 255; // not found, set to default 255
scale = 255/(max - min) * 2; // x2 compensates (play with value)
out.innerHTML = "Min: " + min + " Max: " + max +
" Scale: " + scale.toFixed(1) + "x";
\t
// scale all pixels
for(i = 0; i < data.length; i += 4) {
data[i ] = Math.max(0, data[i] - min) * scale;
data[i+1] = Math.max(0, data[i+1] - min) * scale;
data[i+2] = Math.max(0, data[i+2] - min) * scale;
}
\t
ctx.putImageData(idata, 0, 0)
}
tv.oninput = function() {
v.innerHTML = (tv.value * 100).toFixed(0) + "%";
ctx.drawImage(img, 0, 0);
process(img, +tv.value)
};
function rgb2luma(px, pos) {
return px[pos] * 0.299 + px[pos+1] * 0.587 + px[pos+2] * 0.114
}
<label>Threshold:
<input id=tv type=range min=0 max=1 step= 0.01 value=0.1></label>
<span id=v>10%</span><br>
<canvas id=c></canvas><br>
<div id=out></div>
<h3>Original:</h3>
<img id=org>
완벽 ... 고마워요 ... 미안 해요. 내 일이 다른 우선 순위 때문에 일시 중지되었으므로 올 수 없었습니다. 다시 이전에 .... –
캔버스와 비트 맵 조작. 영구적 일 필요가 없다면 CSS 필터를 적용 할 수 있습니다 (물론 CSS는 자동 조정을 허용하지 않습니다). 자동 조정을 위해 캔버스 + 히스토그램이 필요합니다. – K3N
글쎄, "자동 조정"을 원한다면 현재 이미지 상태를 평가하고 밝기/대비를 어둡게하거나 증가시키는 많은 코드를 작성해야합니다. 사용자의 취향에 따라 밝기와 대비를위한 슬라이더 조정 기능이있는 JS 응용 프로그램을 만드는 것이 더 쉽습니다. 그게 당신의 목표가 아닐 수도 있습니다. 자동 버전의 경우 코드가 @ K3N이 답변에서 제안한 것을 수행하는지 확인하십시오 ... –