Skip to content

Instantly share code, notes, and snippets.

@stuartlynn
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stuartlynn/650d44ec7b1deb3904e3 to your computer and use it in GitHub Desktop.
Save stuartlynn/650d44ec7b1deb3904e3 to your computer and use it in GitHub Desktop.
Kelp processing
require 'pg'
require 'rmagick'
require 'pry'
require 'json'
require 'date'
client = PG.connect(dbname: "world")
no_rows = 20#40
no_colls = 20#40
image_width = 7981
image_height = 7271
scale = 1.0
image_chunk_width = image_width/no_rows
image_chunk_height = image_height/no_colls
target_squares = []
manifest = []
channels = {r:5 , g:4 , b:3}
source = "California"
Dir.glob("/Volumes/zooniverse/kelp-data/#{source}/**").each do |site|
files = Dir.glob("#{site}/*.tar.gz").sample(2)
site_name = site.split("/").last
files.each do |file|
`mkdir -p tmp`
file_name = file.split("/").last
`tar -xzvf #{file} -C tmp/`
base_name = file_name.split(".").first
canvas = Magick::Image::read("tmp/#{base_name}_B4.TIF").first
meta_data = IO.read("tmp/#{base_name}_MTL.txt").split("\n")
lat_long = meta_data.select{|a| a.include?("CORNER_UR_L") || a.include?("CORNER_LL_L")}.inject({}){|r,l| kv=l.split("=").collect{|l| l.strip}; r[kv[0]]= kv[1].to_f ;r}
date = meta_data.select{|a| a.include?("DATE_ACQUIRED")}.first.split("=").last.strip
time = meta_data.select{|a| a.include?("SCENE_CENTER_TIME")}.first.split("=").last.strip
image_time = DateTime.parse(date + " " + time)
full_ll = [ lat_long["CORNER_LL_LON_PRODUCT"], lat_long["CORNER_LL_LAT_PRODUCT"]]
full_ur = [ lat_long["CORNER_UR_LON_PRODUCT"], lat_long["CORNER_UR_LAT_PRODUCT"]]
lon_inc = (full_ll[0] - full_ur[0]) / no_rows
lat_inc = (full_ll[1] - full_ur[1]) / no_colls
gc = Magick::Draw.new
no_rows.times do |r|
no_colls.times do |c|
lon_center = (r+0.5)*lon_inc + full_ll[0]
lat_center = (c+0.5)*lat_inc + full_ll[1]
ll = [ full_ll[0] + (full_ur[0] -full_ll[0])*r/no_rows, full_ll[1] + (full_ur[1] -full_ll[1])*c/no_colls]
ur = [ full_ll[0] + (full_ur[0] -full_ll[0])*(r+1)/no_rows, full_ll[1] + (full_ur[1] -full_ll[1])*(c+1)/no_colls]
result = client.exec("select count(*) as ls from coast where ST_Intersects(ST_SetSRID(ST_MakeBox2D(ST_Point(#{ll.join(",")}), ST_Point(#{ur.join(",")})),4326), geom) ").first["ls"].to_i >0
if result
gc.fill_opacity("50%")
gc.stroke("red")
gc.rectangle((r+1)*image_chunk_width/scale, (no_colls-c)*image_chunk_height/scale, (r + 2)*image_chunk_width/scale, (no_colls-c+1)*image_chunk_height/scale)
target_squares<< [r,c]
rr= r+1
cc= c
gc.stroke("green")
target_squares<< [rr,cc]
gc.rectangle((rr+1)*image_chunk_width/scale, (no_colls-cc)*image_chunk_height/scale, (rr + 2)*image_chunk_width/scale, (no_colls-cc+1)*image_chunk_height/scale)
rr= r-1
cc= c
target_squares<< [rr,cc]
gc.stroke("blue")
gc.rectangle((rr+1)*image_chunk_width/scale, (no_colls-cc)*image_chunk_height/scale, (rr + 2)*image_chunk_width/scale, (no_colls-cc+1)*image_chunk_height/scale)
rr= r
cc= c-1
gc.stroke("yellow")
target_squares<< [rr,cc]
gc.rectangle((rr+1)*image_chunk_width/scale, (no_colls-cc)*image_chunk_height/scale, (rr + 2)*image_chunk_width/scale, (no_colls-cc+1)*image_chunk_height/scale)
rr= r
cc= c+1
gc.stroke("orange")
target_squares<< [rr,cc]
gc.rectangle((rr+1)*image_chunk_width/scale, (no_colls-cc)*image_chunk_height/scale, (rr + 2)*image_chunk_width/scale, (no_colls-cc+1)*image_chunk_height/scale)
end
end
end
`mkdir results/#{base_name}`
target_squares.uniq.each do |target|
channels.each_pair do |c,b|
`convert results/#{base_name}/#{base_name}_B#{b}.TIF -crop #{image_chunk_width}x#{image_chunk_height}+#{image_chunk_width*(target[0])}+#{image_chunk_height*((no_colls-target[1]-1))} -resize 532x484 results/#{base_name}/coast_#{c}_#{target[0]}_#{target[1]}.png`
end
`convert results/#{base_name}/coast_r_#{target[0]}_#{target[1]}.png results/#{base_name}/coast_g_#{target[0]}_#{target[1]}.png results/#{base_name}/coast_b_#{target[0]}_#{target[1]}.png -set colorspace RGB -combine -set colorspace sRGB results/#{base_name}/subejct_#{target[0]}_#{target[1]}.png`
channels.each_pair do |c,b|
`rm results/#{base_name}/coast_#{c}_#{target[0]}_#{target[1]}.png`
end
blank = `identify -format "%k" #{ f }`.to_i < 50
if blank
`rm results/#{base_name}/subejct_#{target[0]}_#{target[1]}.png `
else
ll = [ full_ll[0] + (full_ur[0] -full_ll[0])*r/no_rows, full_ll[1] + (full_ur[1] -full_ll[1])*c/no_colls]
ur = [ full_ll[0] + (full_ur[0] -full_ll[0])*(r+1)/no_rows, full_ll[1] + (full_ur[1] -full_ll[1])*(c+1)/n]
r = target[0]
c = target[1]
manifest << {timestamp: image_time, row_no: r, col_no: c , center: [(ll[0] + ur[0])*0.5,(ll[1]+ur[1])*0.5], lower_left: ll, upper_right: ur, base_file: base_name, no_rows: no_rows, no_colls: no_colls, filename: "results/#{base_name}/subejct_#{target[0]}_#{target[1]}.png", orig_file_name: file_name }
end
end
gc.draw(canvas)
canvas.write("#{base_name}_#{site_name}_overlay.png")
`rm -rf tmp`
end
end
File.open("metadata.json", "w"){|f| f.puts JSON.pretty_generate(manifest)}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment