Skip to content

Instantly share code, notes, and snippets.

@cchudant
Created May 9, 2018 17:45
Show Gist options
  • Save cchudant/db04d3ae9f8286b834a786b769bd7da9 to your computer and use it in GitHub Desktop.
Save cchudant/db04d3ae9f8286b834a786b769bd7da9 to your computer and use it in GitHub Desktop.
const Jimp = require('jimp')
const { readdirSync } = require('fs')
const { join } = require('path')
const floodfill = require('./floodfill')
const sq = i => Math.pow(i, 2)
const distsq = ([ r1, g1, b1 ], [ r2, g2, b2 ]) => sq(r1 - r2) + sq(g1 - g2) + sq(b1 - b2)
//// Variables
const t = sq(0.45 * 255) // difference threshold (distance to raw image)
const t2 = sq(0.35 * 255) // pixel selection threshold (distance to white/black)
const minPixels = 100 // min subtitle pixel amount to trigger file save
////
async function one(raw, sub, to) {
// Read images
const rawi = await Jimp.read(raw)
const subi = await Jimp.read(sub)
const r = rawi.bitmap.data
const s = subi.bitmap.data
// Select the mode (white if image is quite dark and black if image is quite luminous)
let bsum = 0
let wsum = 0
rawi.scan(0, 0, rawi.bitmap.width, rawi.bitmap.height, function (x, y, idx) {
const rColor = [ r[ idx + 0 ], r[ idx + 1 ], r[ idx + 2 ] ]
bsum += distsq(rColor, [ 0, 0, 0 ])
wsum += distsq(rColor, [ 255, 255, 255 ])
})
const usingWhite = bsum < wsum;
console.log(usingWhite ? 'using white mode' : 'using black mode')
// The result image
const result = new Jimp(1280, 720, 0x000000FF)
const res = result.bitmap.data
// Number of triggered pixels
let n = 0
result.scan(0, 0, result.bitmap.width, result.bitmap.height, function (x, y, idx) {
const sColor = [ s[ idx + 0 ], s[ idx + 1 ], s[ idx + 2 ] ]
const rColor = [ r[ idx + 0 ], r[ idx + 1 ], r[ idx + 2 ] ]
if (
( // If pixel in raw image and pixel in sub image are similar
distsq(sColor, rColor) > t
&& ( // Filter white only if white mode or black only if black mode
(usingWhite && distsq(sColor, [ 255, 255, 255 ]) < t2)
|| (!usingWhite && distsq(sColor, [ 0, 0, 0 ]) < t2)
)
)
) { // Flip the pixel in the result image
res[ idx + 0 ] = 255
res[ idx + 1 ] = 255
res[ idx + 2 ] = 255
n++
}
})
console.log('Interesting pixel count:', n)
// If image is interesting (likely to contain subtitle)
if (n > minPixels) {
// Flood fill if black mode (this helps tesseract-ocr read)
if (!usingWhite) {
//floodfill(result, 0, 0, [ 0, 0, 0 ])
}
// Write
await result.write(to)
return true
}
return false
}
const offset = 115
const filename = i => `${i.toString().padStart(7, '0')}.png`
;(async () => {
for (let i = 342; true; i++) {
const rawimg = join('..', 'raw', filename(i))
const subimg = join('..', 'source', filename(i + offset))
const resimg = join('..', 'output', filename(i))
const b = await one(rawimg, subimg, resimg)
console.log(rawimg + ' + ' + subimg + ' => ' + resimg + (b ? ': yesssss!' : ': nop.'))
}
console.log('alldone.')
})().catch(console.error)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment