sclass FaceDataSet { S csvSnippetID = #1032472; // by imageURL new Map entryMap; new L entries; class Entry { S imageURL; File imageFile; new Set facePositions; int w, h; *(S *imageURL) { imageFile = downloadImage(imageURL); } BufferedImage image() { var img = loadImage2(imageFile); if (img == null) print(imageFile + " not found"); else { w = img.getWidth(); h = img.getHeight(); } ret img; } BufferedImage markedImage(int width default w()) { var img = scaleToWidth(image(), width); int height = img.getHeight(); for (var face : facePositions) { Rect r = scaleRect_floor(face, width, height); drawBox(img, r, Color.red, 0.5); } ret img; } int w() { if (w == 0) image(); ret w; } int h() { if (h == 0) image(); ret h; } } File imagesDir() { ret javaxCachesDir("Google Face Data Set"); } File downloadImage(S url) { File file = newFile(imagesDir(), md5FileName(url) + fileExtension(url)); if (file.length() == 0) null; if (!file.exists()) try { loadBinaryPageToFile(url, file); } catch e { if (containsExceptionOfType FileNotFoundException(e)) // as a warning for future generations! saveBinaryFile(file, new byte[0]); } ret file.exists() ? file : null; } void load { for (LS row : parseExtendedCSV_iterator(loadSnippet(csvSnippetID))) { for n to 3: pcall { int i = n*5; S imageURL = convertHttpToHttps(row.get(i++)); Entry e = entryMap.get(imageURL); if (e == null) { e = new Entry(imageURL); if (e.imageFile == null) continue with print("Skipping " + e.imageURL); entryMap.put(imageURL, e); entries.add(e); } e.facePositions.add(doubleRectFromPoints( parseDouble(row.get(i)), // left column (x1) parseDouble(row.get(i+2)), // top row (y1) parseDouble(row.get(i+1)), // right column (x2) parseDouble(row.get(i+3)), // bottom row (y2) )); } } print("Have " + nEntries(entries)); } } /* Row begins: URL of image1 (string) Top-left column of the face bounding box in image1 normalized by width (float) Bottom-right column of the face bounding box in image1 normalized by width (float) Top-left row of the face bounding box in image1 normalized by height (float) Bottom-right row of the face bounding box in image1 normalized by height (float) */