├── .gitignore ├── snapcodes ├── src │ ├── .gitignore │ ├── snapcode.png │ ├── generated │ │ ├── mask.jpeg │ │ ├── all_dots.png │ │ ├── all_dots_yellow.png │ │ └── all_dots_yellow copy.png │ ├── process_all.py │ ├── img_to_svg.py │ ├── points_to_svg.py │ ├── img_to_points.py │ ├── output.svg │ └── exploring │ │ └── snapcodes.ipynb ├── requirements.txt └── README.md ├── spotify-codes-part-2 ├── src │ ├── pics │ │ ├── spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg │ │ └── spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg │ ├── permute.py │ ├── step_by_step.py │ ├── decode_barcode.py │ ├── get_heights.py │ ├── crc.py │ ├── simple_convolutional_code.py │ ├── get_uri.py │ └── encode_decode.py ├── requirements.txt └── README.md ├── spotify-codes ├── calc_crc8.py └── get_heights.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .venv -------------------------------------------------------------------------------- /snapcodes/src/.gitignore: -------------------------------------------------------------------------------- 1 | /imgs 2 | .ipynb_checkpoints/ -------------------------------------------------------------------------------- /snapcodes/src/snapcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boonepeter/boonepeter.github.io-code/HEAD/snapcodes/src/snapcode.png -------------------------------------------------------------------------------- /snapcodes/src/generated/mask.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boonepeter/boonepeter.github.io-code/HEAD/snapcodes/src/generated/mask.jpeg -------------------------------------------------------------------------------- /snapcodes/src/generated/all_dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boonepeter/boonepeter.github.io-code/HEAD/snapcodes/src/generated/all_dots.png -------------------------------------------------------------------------------- /snapcodes/src/generated/all_dots_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boonepeter/boonepeter.github.io-code/HEAD/snapcodes/src/generated/all_dots_yellow.png -------------------------------------------------------------------------------- /snapcodes/src/generated/all_dots_yellow copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boonepeter/boonepeter.github.io-code/HEAD/snapcodes/src/generated/all_dots_yellow copy.png -------------------------------------------------------------------------------- /spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boonepeter/boonepeter.github.io-code/HEAD/spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg -------------------------------------------------------------------------------- /spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boonepeter/boonepeter.github.io-code/HEAD/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg -------------------------------------------------------------------------------- /snapcodes/requirements.txt: -------------------------------------------------------------------------------- 1 | imageio==2.13.5 2 | networkx==2.6.3 3 | numpy==1.22.1 4 | packaging==21.3 5 | Pillow==9.0.0 6 | pyparsing==3.0.6 7 | PyWavelets==1.2.0 8 | scikit-image==0.19.1 9 | scipy==1.7.3 10 | tifffile==2021.11.2 11 | -------------------------------------------------------------------------------- /spotify-codes/calc_crc8.py: -------------------------------------------------------------------------------- 1 | import crc8 2 | 3 | hash = crc8.crc8() 4 | media_ref = 67775490487 5 | ref_bytes = media_ref.to_bytes(5, byteorder="big") 6 | print(ref_bytes) 7 | # b'\x0f\xc7\xbb\xe9\xb7' 8 | hash.update(ref_bytes) 9 | check_bits = hash.digest() 10 | print(check_bits) 11 | # b'\x0c' -------------------------------------------------------------------------------- /spotify-codes-part-2/src/permute.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | def permute(bits, step=7): 5 | for i in range(len(bits)): 6 | yield bits[(i * step) % len(bits)] 7 | 8 | if __name__ == "__main__": 9 | bits = "111000111100101111101110111001011100110000100100011100110011" 10 | print("".join(permute(bits))) 11 | # 111100110001110101101000011110010110101100111111101000111000 12 | -------------------------------------------------------------------------------- /spotify-codes-part-2/src/step_by_step.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | media_ref = 57639171874 6 | binary = f"{bin(media_ref)[2:]:0>37}" 7 | print(binary) 8 | # pad with 3 bits to the right: 9 | binary = f"{binary:0<39}" 10 | print(binary) 11 | 12 | a = "100011100111110100110011110100000010001001011" 13 | b = "110011100010110110110100101101011100110011011" 14 | c = zip(a, b) 15 | print("".join(i + j for i, j in c)) -------------------------------------------------------------------------------- /snapcodes/src/process_all.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from img_to_svg import img_to_svg 4 | 5 | 6 | files = os.listdir("./imgs/twitter") 7 | files = [os.path.join("./imgs/twitter", f) for f in files if f.endswith(".jpeg")] 8 | 9 | for f in files: 10 | output_path = f.replace(".jpeg", ".svg") 11 | try: 12 | img_to_svg(f, output_path) 13 | except Exception as e: 14 | print(f"Error processing {f}") 15 | print(e) -------------------------------------------------------------------------------- /spotify-codes-part-2/requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2020.12.5 2 | chardet==4.0.0 3 | crccheck==1.0 4 | cycler==0.10.0 5 | decorator==4.4.2 6 | idna==2.10 7 | imageio==2.9.0 8 | kiwisolver==1.3.1 9 | matplotlib==3.3.3 10 | networkx==2.5 11 | numpy==1.19.4 12 | Pillow==8.0.1 13 | pyparsing==2.4.7 14 | python-dateutil==2.8.1 15 | PyWavelets==1.1.1 16 | requests==2.25.1 17 | scikit-image==0.18.0 18 | scipy==1.5.4 19 | six==1.15.0 20 | tifffile==2020.12.8 21 | urllib3==1.26.2 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code snippets 2 | 3 | This repo contains the code snippets I reference in [my blog](https://boonepeter.github.io/). 4 | 5 | ## Index 6 | 7 | Code|Blog Post| 8 | ---|---| 9 | [spotify-codes](./spotify-codes)|[How do Spotify Codes Work?](https://boonepeter.github.io/posts/2020-11-10-spotify-codes/)| 10 | [spotify-codes-part-2](./spotify-codes-part-2)|[Spotify Codes Part 2](https://boonepeter.github.io/posts/spotify-codes-part-2/) 11 | [snapcodes](./snapcodes)|No post yet 12 | 13 | -------------------------------------------------------------------------------- /snapcodes/src/img_to_svg.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from img_to_points import img_to_points 3 | from points_to_svg import points_to_svg 4 | 5 | def img_to_svg(filepath, output_filepath): 6 | """ 7 | Converts an image to an SVG file. 8 | """ 9 | points = img_to_points(filepath, True) 10 | print(points) 11 | svg = points_to_svg(points) 12 | with open(output_filepath, "w") as f: 13 | f.write(svg) 14 | 15 | 16 | if __name__ == "__main__": 17 | parser = argparse.ArgumentParser(description="Convert an image to an SVG file.") 18 | parser.add_argument("-i", "--input", help="Input filepath", required=True) 19 | parser.add_argument("-o", "--output", help="Output filepath", required=True) 20 | args = parser.parse_args() 21 | img_to_svg(args.input, args.output) -------------------------------------------------------------------------------- /spotify-codes-part-2/src/decode_barcode.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import pprint 3 | from get_heights import get_heights 4 | from encode_decode import spotify_bar_decode 5 | from get_uri import get_uri, get_info 6 | 7 | 8 | parser = argparse.ArgumentParser(description="Spotify Barcode Decoder.") 9 | 10 | parser.add_argument("filename", help="The filename of the barcode to decode.") 11 | parser.add_argument("--token", required=True, help="Your Spotify authorization token.") 12 | 13 | 14 | 15 | if __name__ == "__main__": 16 | args = parser.parse_args() 17 | filename = args.filename 18 | token = args.token 19 | heights = get_heights(filename) 20 | print(f"Heights: {heights}") 21 | # drop the fist, last, and 12th bar 22 | heights = heights[1:11] + heights[12:-1] 23 | decoded = spotify_bar_decode(heights) 24 | print(f"Media ref: {decoded}") 25 | uri = get_uri(decoded, token) 26 | print(f"URI: {uri['target']}") 27 | summary, full_response = get_info(uri["target"], token) 28 | print("Summary:") 29 | pprint.pprint(summary) 30 | 31 | -------------------------------------------------------------------------------- /spotify-codes-part-2/README.md: -------------------------------------------------------------------------------- 1 | # Spotify Codes Part 2 2 | 3 | ## Install packages 4 | 5 | ```bash 6 | pip3 install -r requirements.txt 7 | ``` 8 | 9 | ## Run 10 | 11 | ```bash 12 | python decode_barcode.py --token="YOUR_TOKEN_HERE" ./pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg 13 | ``` 14 | 15 | ## Token 16 | 17 | This script requires your authorization token to run. You can get this (manually) by visiting [Spotify's Web client](https://open.spotify.com/). If you inspect the page source (F12), you can search for `access_token` in the Network tab after reloading the page. Copy the value and paste it into the `--token` argument. 18 | 19 | ## Output 20 | 21 | ```bash 22 | Heights: [0, 6, 0, 2, 4, 5, 1, 4, 5, 2, 3, 7, 3, 7, 1, 5, 6, 2, 5, 7, 4, 3, 0] 23 | Media ref: 57268659651 24 | URI: spotify:user:spotify:playlist:37i9dQZF1DXcBWIGoYBM5M 25 | Summary: 26 | { 27 | 'description': 'Coldplay & BTS are on top of the Hottest 50!', 28 | 'name': "Today's Top Hits", 29 | 'type': 'playlist', 30 | 'url': 'https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M' 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /spotify-codes-part-2/src/get_heights.py: -------------------------------------------------------------------------------- 1 | from skimage import io 2 | from skimage.measure import label, regionprops 3 | from skimage.filters import threshold_otsu 4 | from skimage.color import rgb2gray 5 | 6 | 7 | def get_heights(filename: str) -> list: 8 | """Open an image and return a list of the bar heights. 9 | """ 10 | image = io.imread(filename) 11 | im = rgb2gray(image) 12 | binary_im = im > threshold_otsu(im) 13 | labeled = label(binary_im) 14 | bar_dimensions = [r.bbox for r in regionprops(labeled)] 15 | bar_dimensions.sort(key=lambda x: x[1], reverse=False) 16 | # the first object (spotify logo) is the max height of the bars 17 | logo = bar_dimensions[0] 18 | max_height = logo[2] - logo[0] 19 | sequence = [] 20 | for bar in bar_dimensions[1:]: 21 | height = bar[2] - bar[0] 22 | ratio = height / max_height 23 | # multiply by 8 to get an octal integer 24 | ratio *= 8 25 | ratio //= 1 26 | # convert to integer (and make 0 based) 27 | sequence.append(int(ratio - 1)) 28 | return sequence -------------------------------------------------------------------------------- /snapcodes/README.md: -------------------------------------------------------------------------------- 1 | # Snapcodes 2 | 3 | Using Python 3.10.1 4 | 5 | ```bash 6 | pip3 install -r requirements.txt 7 | ``` 8 | 9 | Running this command 10 | 11 | ```bash 12 | python3 img_to_points.py snapcode.png 13 | ``` 14 | 15 | Gets the points from this image: 16 | 17 | ![](./src/snapcode.png) 18 | 19 | Points: 20 | 21 | ```python 22 | [1, 2, 3, 4, 6, 9, 14, 18, 20, 21, 22, 23, 27, 28, 29, 30, 32, 38, 39, 41, 43, 44, 45, 49, 53, 58, 59, 62, 64, 65, 66, 67, 70, 71, 73, 76, 77, 83, 87, 90, 93, 94, 96, 99, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 115, 118, 119, 120, 130, 131, 134, 140, 141, 144, 145, 146, 150, 153, 155, 157, 159, 161, 163, 169, 170, 171, 172, 173, 174, 175, 178, 182, 183, 184, 185, 188, 190, 192, 193, 196, 197, 202, 204, 206, 207, 209] 23 | ``` 24 | 25 | Points are numbered left to right, top to bottom, starting with 0 and ending at 211. 26 | 27 | And this command 28 | 29 | ```bash 30 | python3 img_to_svg.py -i snapcode.png -o output.svg 31 | ``` 32 | 33 | Outputs an SVG file: 34 | 35 | ![](./src/output.svg) 36 | 37 | The svg is useful for checking that the point parsing was correct. 38 | -------------------------------------------------------------------------------- /spotify-codes-part-2/src/crc.py: -------------------------------------------------------------------------------- 1 | 2 | def crc(data, polynomial): 3 | n = len(polynomial) - 1 4 | initial_length = len(data) 5 | check_bits = data + [0] * n 6 | for i in range(initial_length): 7 | if check_bits[i] == 1: 8 | for j, p in enumerate(polynomial): 9 | check_bits[i + j] = check_bits[i + j] ^ p 10 | return check_bits[-n:] 11 | 12 | def check_crc(data, polynomial, check_bits): 13 | full_data = data + check_bits 14 | for i in range(len(data)): 15 | if full_data[i] == 1: 16 | for j, p in enumerate(polynomial): 17 | full_data[i + j] = full_data[i + j] ^ p 18 | return 1 not in full_data 19 | data = [0,0,1,0,0,0,1,0,1,1,1,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,1,0,1,0,1,1,0,0,0,0,1,1,0,1] 20 | check = [1,1,0,0,1,1,0,0] 21 | poly = [1,0,0,0,0,0,1,1,1] 22 | print(check_crc(data, poly, check)) 23 | 24 | if __name__ == "__main__": 25 | example = "0010001011110111100011110110101100001101" 26 | long = [int(i) for i in example] 27 | polynomial = [1, 0, 0, 0, 0, 0, 1, 1, 1] # crc8 polynomial 28 | check = crc(long, polynomial) 29 | print(f"Check bits: {check}") 30 | checked = check_crc(long, polynomial, check) 31 | print(f"Checked: {checked}") -------------------------------------------------------------------------------- /spotify-codes/get_heights.py: -------------------------------------------------------------------------------- 1 | from skimage import io 2 | from skimage.measure import label, regionprops 3 | from skimage.filters import threshold_otsu 4 | from skimage.color import rgb2gray 5 | 6 | 7 | def get_heights(filename: str) -> list: 8 | """Open an image and return a list of the bar heights. 9 | """ 10 | # convert to grayscale, then binary 11 | image = io.imread(filename) 12 | im = rgb2gray(image) 13 | binary_im = im > threshold_otsu(im) 14 | 15 | # label connected regions as objects 16 | labeled = label(binary_im) 17 | 18 | # get the dimensions and positions of bounding box around objects 19 | bar_dimensions = [r.bbox for r in regionprops(labeled)] 20 | 21 | # sort by X 22 | bar_dimensions.sort(key=lambda x: x[1], reverse=False) 23 | 24 | # the first object (spotify logo) is the max height of the bars 25 | logo = bar_dimensions[0] 26 | max_height = logo[2] - logo[0] 27 | sequence = [] 28 | for bar in bar_dimensions[1:]: 29 | height = bar[2] - bar[0] 30 | ratio = height / max_height 31 | # multiply by 8 to get an octal integer 32 | ratio *= 8 33 | ratio //= 1 34 | # convert to integer (and make 0 based) 35 | sequence.append(int(ratio - 1)) 36 | return sequence -------------------------------------------------------------------------------- /spotify-codes-part-2/src/simple_convolutional_code.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def encode(bits: List[int], polynomial: List[int], tail_bite=False): 5 | """Convolutionally encode the stream of bits using the generator polynomial. 6 | If tail_bite == True, prepend the tail of the input. Otherwise use 0s to fill. 7 | """ 8 | if tail_bite: 9 | tail = bits[-(len(polynomial) - 1):] 10 | else: 11 | tail = [0 for i in range(len(polynomial) - 1)] 12 | full = tail + bits 13 | polynomial.reverse() # Reverse since we're working the other direction 14 | parity_bits = [] 15 | for i in range(len(bits)): 16 | parity = 0 17 | for j in range(len(polynomial)): 18 | parity ^= full[i + j] * polynomial[j] 19 | parity_bits.append(parity) 20 | return parity_bits 21 | 22 | 23 | if __name__ == "__main__": 24 | g0 = [1, 0, 1, 1, 0, 1, 1] 25 | g1 = [1, 1, 1, 1, 0, 0, 1] 26 | bits = "010001001110111111110001110101101011011001100" 27 | g0_expected = "100011100111110100110011110100000010001001011" 28 | g1_expected = "110011100010110110110100101101011100110011011" 29 | bits = [int(i) for i in bits] 30 | 31 | p0 = encode(bits, g0, True) 32 | p1 = encode(bits, g1, True) 33 | 34 | print(g0_expected == "".join(str(i) for i in p0)) 35 | print(g1_expected == "".join(str(i) for i in p1)) -------------------------------------------------------------------------------- /spotify-codes-part-2/src/get_uri.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | import requests 3 | 4 | HEADERS_LUT = { 5 | "X-Client-Id": "58bd3c95768941ea9eb4350aaa033eb3", 6 | "Accept-Encoding": "gzip, deflate", 7 | "Connection": "close", 8 | "App-Platform": "iOS", 9 | "Accept": "*/*", 10 | "User-Agent": "Spotify/8.5.68 iOS/13.4 (iPhone9,3)", 11 | "Accept-Language": "en", 12 | "Spotify-App-Version": "8.5.68", 13 | } 14 | MEDIA_REF_LUT_URL = "https://spclient.wg.spotify.com:443/scannable-id/id" 15 | 16 | def get_uri(media_ref: int, token: str): 17 | """Query Spotify internal API to get the URI of the media reference.""" 18 | header = { 19 | **HEADERS_LUT, 20 | "Authorization": f"Bearer {token}" 21 | } 22 | url = f'{MEDIA_REF_LUT_URL}/{media_ref}?format=json' 23 | response = requests.get(url, headers=header) 24 | response.raise_for_status() 25 | return response.json() 26 | 27 | def get_info(uri: str, token: str) -> Tuple[dict, dict]: 28 | """Query the Spotify API to get information about a URI.""" 29 | info_headers = { 30 | "Content-Type": "application/json", 31 | "Accept": "application/json", 32 | "Authorization": f"Bearer {token}" 33 | } 34 | split = uri.split(":") 35 | content_type = split[-2] + "s" 36 | id = split[-1] 37 | response = requests.get(f"https://api.spotify.com/v1/{content_type}/{id}", headers=info_headers) 38 | response.raise_for_status() 39 | resp = response.json() 40 | result = { 41 | "name": resp["name"], 42 | "type": split[-2], 43 | "url": resp["external_urls"]["spotify"], 44 | } 45 | if "artists" in resp: 46 | result['artists'] = [] 47 | for a in resp['artists']: 48 | result["artists"].append(a["name"]) 49 | if "album" in resp: 50 | result['album'] = resp['album']['name'] 51 | 52 | if "description" in resp: 53 | result["description"] = resp['description'] 54 | 55 | return result, resp 56 | 57 | -------------------------------------------------------------------------------- /snapcodes/src/points_to_svg.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | positions = [ 4 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], 5 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 6 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 7 | [0, 1, 2, 3, 4, 5, 13, 14, 15, 16, 17, 18], 8 | [0, 1, 2, 3, 4, 14, 15, 16, 17, 18], 9 | [0, 1, 2, 3, 15, 16, 17, 18], 10 | [0, 1, 2, 16, 17, 18], 11 | [0, 1, 2, 16, 17, 18], 12 | [0, 1, 2, 16, 17, 18], 13 | [0, 1, 2, 16, 17, 18], 14 | [0, 1, 2, 16, 17, 18], 15 | [0, 1, 2, 16, 17, 18], 16 | [0, 1, 2, 16, 17, 18], 17 | [0, 1, 2, 3, 15, 16, 17, 18], 18 | [0, 1, 2, 3, 4, 14, 15, 16, 17, 18], 19 | [0, 1, 2, 3, 4, 5, 13, 14, 15, 16, 17, 18], 20 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 21 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 22 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], 23 | ] 24 | 25 | BORDER = 56.42 26 | BORDER_C = 72.42 27 | MULT = 48.8425 28 | DIAMETER = 32 29 | SVG = ''' 30 | 31 | 32 | 34 | 35 | ''' 36 | 37 | def points_to_svg(points): 38 | counter = 0 39 | path = "" 40 | points.sort() 41 | for r in range(len(positions)): 42 | for c in range(len(positions[r])): 43 | col = positions[r][c] 44 | if len(points) == 0: 45 | break 46 | if points[0] == counter: 47 | path += f"""M{col * MULT + BORDER_C},{r * MULT + BORDER} 48 | A16,16,0,0,0,{col * MULT + BORDER_C},{r * MULT + BORDER + DIAMETER} 49 | A16,16,0,0,0,{col * MULT + BORDER_C},{r * MULT + BORDER} 50 | """ 51 | points.pop(0) 52 | counter += 1 53 | return SVG.format(path=path) 54 | 55 | 56 | if __name__ == "__main__": 57 | parser = argparse.ArgumentParser() 58 | parser.add_argument("--points", type=str, help="Points to draw") 59 | parser.add_argument("--output", type=str, help="Output file") 60 | parser.add_argument("--show", action="store_true", help="Show SVG") 61 | parser.set_defaults(points=",".join([str(i) for i in range(212)])) 62 | args = parser.parse_args() 63 | points = args.points.split(",") 64 | points = [int(i) for i in points] 65 | svg = points_to_svg(points) 66 | if args.output: 67 | with open(args.output, "w") as f: 68 | f.write(svg) 69 | if args.show: 70 | import subprocess, os, platform 71 | if platform.system() == 'Darwin': # macOS 72 | subprocess.call(('open', args.output)) 73 | elif platform.system() == 'Windows': # Windows 74 | os.startfile(args.output) 75 | else: # linux variants 76 | subprocess.call(('xdg-open', args.output)) 77 | if not args.show or not args.output: 78 | print(svg) 79 | -------------------------------------------------------------------------------- /spotify-codes-part-2/src/encode_decode.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import crccheck 3 | 4 | # This code was written by "Doyle" on Stack Overflow 5 | # https://stackoverflow.com/a/64950150/10703868 6 | 7 | 8 | # Utils for conversion between int, array of binary 9 | # and array of bytes (as ints) 10 | def int_to_bin(num, length, endian): 11 | if endian == 'l': 12 | return [num >> i & 1 for i in range(0, length)] 13 | elif endian == 'b': 14 | return [num >> i & 1 for i in range(length-1, -1, -1)] 15 | 16 | def bin_to_int(bin,length): 17 | return int("".join([str(bin[i]) for i in range(length-1,-1,-1)]),2) 18 | 19 | def bin_to_bytes(bin, length): 20 | b = bin[0:length] + [0] * (-length % 8) 21 | return [(b[i]<<7) + (b[i+1]<<6) + (b[i+2]<<5) + (b[i+3]<<4) + 22 | (b[i+4]<<3) + (b[i+5]<<2) + (b[i+6]<<1) + b[i+7] for i in range(0,len(b),8)] 23 | 24 | # Return the circular right shift of an array by 'n' positions 25 | def shift_right(arr, n): 26 | return arr[-n % len(arr):len(arr):] + arr[0:-n % len(arr)] 27 | 28 | gray_code = [0,1,3,2,7,6,4,5] 29 | gray_code_inv = [[0,0,0],[0,0,1],[0,1,1],[0,1,0], 30 | [1,1,0],[1,1,1],[1,0,1],[1,0,0]] 31 | 32 | # CRC using Rocksoft model: 33 | # NOTE: this is not quite any of their predefined CRC's 34 | # 8: number of check bits (degree of poly) 35 | # 0x7: representation of poly without high term (x^8+x^2+x+1) 36 | # 0x0: initial fill of register 37 | # True: byte reverse data 38 | # True: byte reverse check 39 | # 0xff: Mask check (i.e. invert) 40 | spotify_crc = crccheck.crc.Crc(8, 0x7, 0x0, True, True, 0xff) 41 | 42 | def calc_spotify_crc(bin37): 43 | bytes = bin_to_bytes(bin37, 37) 44 | return int_to_bin(spotify_crc.calc(bytes), 8, 'b') 45 | 46 | def check_spotify_crc(bin45): 47 | data = bin_to_bytes(bin45,37) 48 | return spotify_crc.calc(data) == bin_to_bytes(bin45[37:], 8)[0] 49 | 50 | # Simple convolutional encoder 51 | def encode_cc(dat): 52 | gen1 = [1,0,1,1,0,1,1] 53 | gen2 = [1,1,1,1,0,0,1] 54 | punct = [1,1,0] 55 | dat_pad = dat[-6:] + dat # 6 bits are needed to initialize 56 | # register for tail-biting 57 | stream1 = np.convolve(dat_pad, gen1, mode='valid') % 2 58 | stream2 = np.convolve(dat_pad, gen2, mode='valid') % 2 59 | enc = [val for pair in zip(stream1, stream2) for val in pair] 60 | return [enc[i] for i in range(len(enc)) if punct[i % 3]] 61 | 62 | # To create a generator matrix for a code, we encode each row 63 | # of the identity matrix. Note that the CRC is not quite linear 64 | # because of the check mask so we apply the lamda function to 65 | # invert it. Given a 37 bit media reference we can encode by 66 | # ref * spotify_generator + spotify_mask (mod 2) 67 | _i37 = np.identity(37, dtype=bool) 68 | crc_generator = [_i37[r].tolist() + 69 | list(map(lambda x : 1-x, calc_spotify_crc(_i37[r].tolist()))) 70 | for r in range(37)] 71 | spotify_generator = 1*np.array([encode_cc(crc_generator[r]) for r in range(37)], dtype=bool) 72 | del _i37 73 | 74 | spotify_mask = 1*np.array(encode_cc(37*[0] + 8*[1]), dtype=bool) 75 | 76 | # The following matrix is used to "invert" the convolutional code. 77 | # In particular, we choose a 45 vector basis for the columns of the 78 | # generator matrix (by deleting those in positions equal to 2 mod 4) 79 | # and then inverting the matrix. By selecting the corresponding 45 80 | # elements of the convolutionally encoded vector and multiplying 81 | # on the right by this matrix, we get back to the unencoded data, 82 | # assuming there are no errors. 83 | # Note: numpy does not invert binary matrices, i.e. GF(2), so we 84 | # hard code the following 3 row vectors to generate the matrix. 85 | conv_gen = [[0,1,0,1,1,1,1,0,1,1,0,0,0,1]+31*[0], 86 | [1,0,1,0,1,0,1,0,0,0,1,1,1] + 32*[0], 87 | [0,0,1,0,1,1,1,1,1,1,0,0,1] + 32*[0] ] 88 | 89 | conv_generator_inv = 1*np.array([shift_right(conv_gen[(s-27) % 3],s) for s in range(27,72)], dtype=bool) 90 | 91 | 92 | # Given an integer media reference, returns list of 20 barcode levels 93 | def spotify_bar_code(ref): 94 | bin37 = np.array([int_to_bin(ref, 37, 'l')], dtype=bool) 95 | enc = (np.add(1*np.dot(bin37, spotify_generator), spotify_mask) % 2).flatten() 96 | perm = [enc[7*i % 60] for i in range(60)] 97 | return [gray_code[4*perm[i]+2*perm[i+1]+perm[i+2]] for i in range(0,len(perm),3)] 98 | 99 | # Equivalent function but using CRC and CC encoders. 100 | def spotify_bar_code2(ref): 101 | bin37 = int_to_bin(ref, 37, 'l') 102 | enc_crc = bin37 + calc_spotify_crc(bin37) 103 | enc_cc = encode_cc(enc_crc) 104 | perm = [enc_cc[7*i % 60] for i in range(60)] 105 | return [gray_code[4*perm[i]+2*perm[i+1]+perm[i+2]] for i in range(0,len(perm),3)] 106 | 107 | # Given 20 (clean) barcode levels, returns media reference 108 | def spotify_bar_decode(levels): 109 | level_bits = np.array([gray_code_inv[levels[i]] for i in range(20)], dtype=bool).flatten() 110 | conv_bits = [level_bits[43*i % 60] for i in range(60)] 111 | cols = [i for i in range(60) if i % 4 != 2] # columns to invert 112 | conv_bits45 = np.array([conv_bits[c] for c in cols], dtype=bool) 113 | bin45 = (1*np.dot(conv_bits45, conv_generator_inv) % 2).tolist() 114 | if check_spotify_crc(bin45): 115 | return bin_to_int(bin45, 37) 116 | else: 117 | print('Error in levels; Use real decoder!!!') 118 | return -1 -------------------------------------------------------------------------------- /snapcodes/src/img_to_points.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from skimage import io 3 | import numpy as np 4 | from skimage import io, img_as_ubyte 5 | from skimage.filters import threshold_otsu 6 | from skimage.color import rgb2gray, rgba2rgb 7 | from skimage.measure import label, regionprops 8 | 9 | ## BBOX of points from all_dots_yellow.png 10 | ALL_BBOX = [ 11 | [0.025, 0.076, 0.0583, 0.1094], 12 | [0.025, 0.1271, 0.0583, 0.1604], 13 | [0.025, 0.1781, 0.0583, 0.2115], 14 | [0.025, 0.2292, 0.0583, 0.2625], 15 | [0.025, 0.2802, 0.0583, 0.3135], 16 | [0.025, 0.3302, 0.0583, 0.3635], 17 | [0.025, 0.3812, 0.0583, 0.4146], 18 | [0.025, 0.4323, 0.0583, 0.4656], 19 | [0.025, 0.4833, 0.0583, 0.5167], 20 | [0.025, 0.5344, 0.0583, 0.5677], 21 | [0.025, 0.5854, 0.0583, 0.6188], 22 | [0.025, 0.6365, 0.0583, 0.6698], 23 | [0.025, 0.6865, 0.0583, 0.7198], 24 | [0.025, 0.7375, 0.0583, 0.7708], 25 | [0.025, 0.7885, 0.0583, 0.8219], 26 | [0.025, 0.8396, 0.0583, 0.8729], 27 | [0.025, 0.8906, 0.0583, 0.924], 28 | [0.076, 0.025, 0.1094, 0.0583], 29 | [0.076, 0.076, 0.1094, 0.1094], 30 | [0.076, 0.1271, 0.1094, 0.1604], 31 | [0.076, 0.1781, 0.1094, 0.2115], 32 | [0.076, 0.2292, 0.1094, 0.2625], 33 | [0.076, 0.2802, 0.1094, 0.3135], 34 | [0.076, 0.3302, 0.1094, 0.3635], 35 | [0.076, 0.3812, 0.1094, 0.4146], 36 | [0.076, 0.4323, 0.1094, 0.4656], 37 | [0.076, 0.4833, 0.1094, 0.5167], 38 | [0.076, 0.5344, 0.1094, 0.5677], 39 | [0.076, 0.5854, 0.1094, 0.6188], 40 | [0.076, 0.6365, 0.1094, 0.6698], 41 | [0.076, 0.6865, 0.1094, 0.7198], 42 | [0.076, 0.7375, 0.1094, 0.7708], 43 | [0.076, 0.7885, 0.1094, 0.8219], 44 | [0.076, 0.8396, 0.1094, 0.8729], 45 | [0.076, 0.8906, 0.1094, 0.924], 46 | [0.076, 0.9417, 0.1094, 0.975], 47 | [0.1271, 0.025, 0.1604, 0.0583], 48 | [0.1271, 0.076, 0.1604, 0.1094], 49 | [0.1271, 0.1271, 0.1604, 0.1604], 50 | [0.1271, 0.1781, 0.1604, 0.2115], 51 | [0.1271, 0.2292, 0.1604, 0.2625], 52 | [0.1271, 0.2802, 0.1604, 0.3135], 53 | [0.1271, 0.3312, 0.1604, 0.3635], 54 | [0.1271, 0.3812, 0.1604, 0.4146], 55 | [0.1271, 0.4323, 0.1604, 0.4656], 56 | [0.1271, 0.4833, 0.1604, 0.5167], 57 | [0.1271, 0.5344, 0.1604, 0.5677], 58 | [0.1271, 0.5854, 0.1604, 0.6188], 59 | [0.1271, 0.6365, 0.1604, 0.6698], 60 | [0.1271, 0.6865, 0.1604, 0.7198], 61 | [0.1271, 0.7375, 0.1604, 0.7708], 62 | [0.1271, 0.7885, 0.1604, 0.8219], 63 | [0.1271, 0.8396, 0.1604, 0.8729], 64 | [0.1271, 0.8906, 0.1604, 0.924], 65 | [0.1271, 0.9417, 0.1604, 0.975], 66 | [0.1781, 0.025, 0.2115, 0.0583], 67 | [0.1781, 0.076, 0.2115, 0.1094], 68 | [0.1781, 0.1271, 0.2115, 0.1604], 69 | [0.1781, 0.1781, 0.2115, 0.2115], 70 | [0.1781, 0.2292, 0.2115, 0.2625], 71 | [0.1781, 0.2802, 0.2115, 0.3135], 72 | [0.1781, 0.6865, 0.2115, 0.7198], 73 | [0.1781, 0.7375, 0.2115, 0.7708], 74 | [0.1781, 0.7885, 0.2115, 0.8219], 75 | [0.1781, 0.8396, 0.2115, 0.8729], 76 | [0.1781, 0.8906, 0.2115, 0.924], 77 | [0.1781, 0.9417, 0.2115, 0.975], 78 | [0.2292, 0.025, 0.2625, 0.0583], 79 | [0.2292, 0.076, 0.2625, 0.1094], 80 | [0.2292, 0.1271, 0.2625, 0.1604], 81 | [0.2292, 0.1781, 0.2625, 0.2115], 82 | [0.2292, 0.2292, 0.2625, 0.2625], 83 | [0.2292, 0.7375, 0.2625, 0.7708], 84 | [0.2292, 0.7885, 0.2625, 0.8219], 85 | [0.2292, 0.8396, 0.2625, 0.8729], 86 | [0.2292, 0.8906, 0.2625, 0.924], 87 | [0.2292, 0.9417, 0.2625, 0.975], 88 | [0.2802, 0.025, 0.3135, 0.0583], 89 | [0.2802, 0.076, 0.3135, 0.1094], 90 | [0.2802, 0.1271, 0.3135, 0.1604], 91 | [0.2802, 0.1781, 0.3135, 0.2115], 92 | [0.2802, 0.7885, 0.3135, 0.8219], 93 | [0.2802, 0.8396, 0.3135, 0.8729], 94 | [0.2802, 0.8906, 0.3135, 0.924], 95 | [0.2802, 0.9417, 0.3135, 0.975], 96 | [0.3302, 0.025, 0.3635, 0.0583], 97 | [0.3302, 0.076, 0.3635, 0.1094], 98 | [0.3302, 0.1271, 0.3635, 0.1604], 99 | [0.3302, 0.8396, 0.3635, 0.8729], 100 | [0.3302, 0.8906, 0.3635, 0.924], 101 | [0.3302, 0.9417, 0.3635, 0.975], 102 | [0.3812, 0.025, 0.4146, 0.0583], 103 | [0.3812, 0.076, 0.4146, 0.1094], 104 | [0.3812, 0.1271, 0.4146, 0.1604], 105 | [0.3812, 0.8396, 0.4146, 0.8729], 106 | [0.3812, 0.8906, 0.4146, 0.924], 107 | [0.3812, 0.9417, 0.4146, 0.975], 108 | [0.4323, 0.025, 0.4656, 0.0583], 109 | [0.4323, 0.076, 0.4656, 0.1094], 110 | [0.4323, 0.1271, 0.4656, 0.1604], 111 | [0.4323, 0.8396, 0.4656, 0.8729], 112 | [0.4323, 0.8906, 0.4656, 0.924], 113 | [0.4323, 0.9417, 0.4656, 0.975], 114 | [0.4833, 0.025, 0.5167, 0.0583], 115 | [0.4833, 0.076, 0.5167, 0.1094], 116 | [0.4833, 0.1271, 0.5167, 0.1604], 117 | [0.4833, 0.8396, 0.5167, 0.8729], 118 | [0.4833, 0.8906, 0.5167, 0.924], 119 | [0.4833, 0.9417, 0.5167, 0.975], 120 | [0.5344, 0.025, 0.5677, 0.0583], 121 | [0.5344, 0.076, 0.5677, 0.1094], 122 | [0.5344, 0.1271, 0.5677, 0.1604], 123 | [0.5344, 0.8396, 0.5677, 0.8729], 124 | [0.5344, 0.8906, 0.5677, 0.924], 125 | [0.5344, 0.9417, 0.5677, 0.975], 126 | [0.5854, 0.025, 0.6188, 0.0583], 127 | [0.5854, 0.076, 0.6188, 0.1094], 128 | [0.5854, 0.1271, 0.6188, 0.1604], 129 | [0.5854, 0.8396, 0.6188, 0.8729], 130 | [0.5854, 0.8906, 0.6188, 0.924], 131 | [0.5854, 0.9417, 0.6188, 0.975], 132 | [0.6365, 0.025, 0.6698, 0.0583], 133 | [0.6365, 0.076, 0.6698, 0.1094], 134 | [0.6365, 0.1271, 0.6698, 0.1604], 135 | [0.6365, 0.8396, 0.6698, 0.8729], 136 | [0.6365, 0.8906, 0.6698, 0.924], 137 | [0.6365, 0.9417, 0.6698, 0.975], 138 | [0.6865, 0.025, 0.7198, 0.0583], 139 | [0.6865, 0.076, 0.7198, 0.1094], 140 | [0.6865, 0.1271, 0.7198, 0.1604], 141 | [0.6865, 0.1781, 0.7198, 0.2115], 142 | [0.6865, 0.7885, 0.7198, 0.8219], 143 | [0.6865, 0.8396, 0.7198, 0.8729], 144 | [0.6865, 0.8906, 0.7198, 0.924], 145 | [0.6865, 0.9417, 0.7198, 0.975], 146 | [0.7375, 0.025, 0.7708, 0.0583], 147 | [0.7375, 0.076, 0.7708, 0.1094], 148 | [0.7375, 0.1271, 0.7708, 0.1604], 149 | [0.7375, 0.1781, 0.7708, 0.2115], 150 | [0.7375, 0.2292, 0.7708, 0.2625], 151 | [0.7375, 0.7375, 0.7708, 0.7708], 152 | [0.7375, 0.7885, 0.7708, 0.8219], 153 | [0.7375, 0.8396, 0.7708, 0.8729], 154 | [0.7375, 0.8906, 0.7708, 0.924], 155 | [0.7375, 0.9417, 0.7708, 0.975], 156 | [0.7885, 0.025, 0.8219, 0.0583], 157 | [0.7885, 0.076, 0.8219, 0.1094], 158 | [0.7885, 0.1271, 0.8219, 0.1604], 159 | [0.7885, 0.1781, 0.8219, 0.2115], 160 | [0.7885, 0.2292, 0.8219, 0.2625], 161 | [0.7885, 0.2802, 0.8219, 0.3135], 162 | [0.7885, 0.6865, 0.8219, 0.7198], 163 | [0.7885, 0.7375, 0.8219, 0.7708], 164 | [0.7885, 0.7885, 0.8219, 0.8219], 165 | [0.7885, 0.8396, 0.8219, 0.8729], 166 | [0.7885, 0.8906, 0.8219, 0.924], 167 | [0.7885, 0.9417, 0.8219, 0.975], 168 | [0.8396, 0.025, 0.8729, 0.0583], 169 | [0.8396, 0.076, 0.8729, 0.1094], 170 | [0.8396, 0.1271, 0.8729, 0.1604], 171 | [0.8396, 0.1781, 0.8729, 0.2115], 172 | [0.8396, 0.2292, 0.8729, 0.2625], 173 | [0.8396, 0.2802, 0.8729, 0.3135], 174 | [0.8396, 0.3312, 0.8729, 0.3635], 175 | [0.8396, 0.3812, 0.8729, 0.4146], 176 | [0.8396, 0.4323, 0.8729, 0.4656], 177 | [0.8396, 0.4833, 0.8729, 0.5167], 178 | [0.8396, 0.5344, 0.8729, 0.5677], 179 | [0.8396, 0.5854, 0.8729, 0.6188], 180 | [0.8396, 0.6365, 0.8729, 0.6698], 181 | [0.8396, 0.6865, 0.8729, 0.7198], 182 | [0.8396, 0.7375, 0.8729, 0.7708], 183 | [0.8396, 0.7885, 0.8729, 0.8219], 184 | [0.8396, 0.8396, 0.8729, 0.8729], 185 | [0.8396, 0.8906, 0.8729, 0.924], 186 | [0.8396, 0.9417, 0.8729, 0.975], 187 | [0.8906, 0.025, 0.924, 0.0583], 188 | [0.8906, 0.076, 0.924, 0.1094], 189 | [0.8906, 0.1271, 0.924, 0.1604], 190 | [0.8906, 0.1781, 0.924, 0.2115], 191 | [0.8906, 0.2292, 0.924, 0.2625], 192 | [0.8906, 0.2802, 0.924, 0.3135], 193 | [0.8906, 0.3302, 0.924, 0.3635], 194 | [0.8906, 0.3812, 0.924, 0.4146], 195 | [0.8906, 0.4323, 0.924, 0.4656], 196 | [0.8906, 0.4833, 0.924, 0.5167], 197 | [0.8906, 0.5344, 0.924, 0.5677], 198 | [0.8906, 0.5854, 0.924, 0.6188], 199 | [0.8906, 0.6365, 0.924, 0.6698], 200 | [0.8906, 0.6865, 0.924, 0.7198], 201 | [0.8906, 0.7375, 0.924, 0.7708], 202 | [0.8906, 0.7885, 0.924, 0.8219], 203 | [0.8906, 0.8396, 0.924, 0.8729], 204 | [0.8906, 0.8906, 0.924, 0.924], 205 | [0.8906, 0.9417, 0.924, 0.975], 206 | [0.9417, 0.076, 0.975, 0.1094], 207 | [0.9417, 0.1271, 0.975, 0.1604], 208 | [0.9417, 0.1781, 0.975, 0.2115], 209 | [0.9417, 0.2292, 0.975, 0.2625], 210 | [0.9417, 0.2802, 0.975, 0.3135], 211 | [0.9417, 0.3302, 0.975, 0.3635], 212 | [0.9417, 0.3812, 0.975, 0.4146], 213 | [0.9417, 0.4323, 0.975, 0.4656], 214 | [0.9417, 0.4833, 0.975, 0.5167], 215 | [0.9417, 0.5344, 0.975, 0.5677], 216 | [0.9417, 0.5854, 0.975, 0.6188], 217 | [0.9417, 0.6365, 0.975, 0.6698], 218 | [0.9417, 0.6865, 0.975, 0.7198], 219 | [0.9417, 0.7375, 0.975, 0.7708], 220 | [0.9417, 0.7885, 0.975, 0.8219], 221 | [0.9417, 0.8396, 0.975, 0.8729], 222 | [0.9417, 0.8906, 0.975, 0.924], 223 | ] 224 | 225 | def color_crop(im, color=[(250, 255), (245, 255), (0, 10)]): 226 | """Crop an image to the min and max occurances of a color range. 227 | Accepts an image and list of colors (channels and colors must match). 228 | """ 229 | assert len(color) == im.shape[-1] 230 | binary = np.ones(im.shape[:-1], dtype=bool) 231 | for i in range(3): 232 | binary &= (im[:,:,i] >= color[i][0]) & (im[:,:,i] <= color[i][1]) 233 | labeled = label(binary, background=0) 234 | rp = regionprops(labeled) 235 | bbox = max(rp, key=lambda x: x.bbox_area).bbox 236 | return im[bbox[0]:bbox[2], bbox[1]:bbox[3], :] 237 | 238 | def _get_points(image): 239 | im = rgb2gray(image) 240 | t = threshold_otsu(im) 241 | return im > t 242 | 243 | 244 | def get_bbox_and_centers(im, color=[(250, 255), (245, 255), (0, 10)]): 245 | im = color_crop(im, color=color) 246 | p = _get_points(im) 247 | l = label(p, background=1) 248 | rp = regionprops(l) 249 | (maxx, maxy) = l.shape 250 | max_size = l.shape[0] * l.shape[1] // 500 251 | min_size = l.shape[0] * l.shape[1] // 2000 252 | 253 | bbs = [] 254 | centers = [] 255 | for props in rp: 256 | minr, minc, maxr, maxc = props.bbox 257 | if props.bbox_area < max_size and props.bbox_area > min_size: 258 | bbs.append((props.bbox[0] / maxx, props.bbox[1] / maxx, props.bbox[2] / maxx, props.bbox[3] / maxx)) 259 | centers.append( 260 | ( 261 | (((minr / maxy) + (maxr / maxy)) / 2), 262 | (((minc / maxx) + (maxc / maxx)) / 2) 263 | ), 264 | ) 265 | return bbs, centers 266 | 267 | def get_numbers(centers, bbs): 268 | points = [] 269 | for i, b in enumerate(bbs): 270 | for x, y in centers: 271 | if x > b[0] and x < b[2] and y > b[1] and y < b[3]: 272 | points.append(i) 273 | return points 274 | 275 | def img_to_points(filepath, check_counts=False): 276 | im = io.imread(filepath) 277 | color = [(250, 255), (245, 255), (0, 10)] 278 | # convert to 3 channel 279 | if im.shape[-1] == 4: 280 | im = rgba2rgb(im) 281 | # convert to uint8 (0-255) 282 | im = img_as_ubyte(im) 283 | try: 284 | _, centers = get_bbox_and_centers(im, color) 285 | except: 286 | try: 287 | # for some reason, some of the colors are off 288 | # when the images are read in 289 | color = [(250, 255), (245, 255), (75, 90)] 290 | _, centers = get_bbox_and_centers(im, color) 291 | except Exception as e: 292 | raise e 293 | if check_counts and (len(centers) < 50 or len(centers) > 120): 294 | raise Exception("Too many or too few points") 295 | return get_numbers(centers, ALL_BBOX) 296 | 297 | 298 | if __name__ == "__main__": 299 | parser = argparse.ArgumentParser() 300 | parser.add_argument("filepath", type=str) 301 | parser.add_argument("--check_counts", action="store_true") 302 | args = parser.parse_args() 303 | print(img_to_points(args.filepath, args.check_counts)) 304 | 305 | 306 | -------------------------------------------------------------------------------- /snapcodes/src/output.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 300 | 301 | -------------------------------------------------------------------------------- /snapcodes/src/exploring/snapcodes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "id": "turned-listening", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import os\n", 11 | "import matplotlib.pyplot as plt\n", 12 | "from skimage import io, img_as_ubyte\n", 13 | "from skimage.filters import threshold_otsu\n", 14 | "from skimage.color import rgb2gray\n", 15 | "from skimage.measure import label, regionprops\n", 16 | "from skimage.transform import resize, rotate" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 4, 22 | "id": "healthy-curve", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "folder = \"./imgs/new\"\n", 27 | "\n", 28 | "files = [os.path.join(folder, i) for i in os.listdir(folder) if not i == '.DS_Store']\n", 29 | "\n" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 11, 35 | "id": "legal-rebate", 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "def im_to_binary(im, w=1000, h=1000, mask=None):\n", 40 | " \n", 41 | " i = io.imread(im)\n", 42 | " i = rgb2gray(i)\n", 43 | " if mask is not None:\n", 44 | " i = resize(i, (mask.shape[0], mask.shape[1]))\n", 45 | " i = i & mask\n", 46 | " else:\n", 47 | " i = resize(i, (w, h))\n", 48 | "\n", 49 | " t = threshold_otsu(i)\n", 50 | " return i > t\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 12, 56 | "id": "interior-climb", 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "filepath = 'imgs/mask.jpeg'\n", 61 | "im = io.imread(filepath)\n", 62 | "mask = im > threshold_otsu(im)" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 14, 68 | "id": "fantastic-attention", 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stderr", 73 | "output_type": "stream", 74 | "text": [ 75 | ":4: FutureWarning: Non RGB image conversion is now deprecated. For RGBA images, please use rgb2gray(rgba2rgb(rgb)) instead. In version 0.19, a ValueError will be raised if input image last dimension length is not 3.\n", 76 | " i = rgb2gray(i)\n" 77 | ] 78 | }, 79 | { 80 | "ename": "TypeError", 81 | "evalue": "unsupported operand type(s) for -: 'NoneType' and 'int'", 82 | "output_type": "error", 83 | "traceback": [ 84 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 85 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 86 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mim_to_binary\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfiles\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mf\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfiles\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mim_to_binary\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mj\u001b[0m \u001b[0;34m&=\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg_as_ubyte\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 87 | "\u001b[0;32m\u001b[0m in \u001b[0;36mim_to_binary\u001b[0;34m(im, w, h, mask)\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m&\u001b[0m \u001b[0mmask\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0mi\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mw\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mh\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mthreshold_otsu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 88 | "\u001b[0;32m/usr/local/lib/python3.9/site-packages/skimage/transform/_warps.py\u001b[0m in \u001b[0;36mresize\u001b[0;34m(image, output_shape, order, mode, cval, clip, preserve_range, anti_aliasing, anti_aliasing_sigma)\u001b[0m\n\u001b[1;32m 160\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 161\u001b[0m \u001b[0;31m# 3 control points necessary to estimate exact AffineTransform\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 162\u001b[0;31m \u001b[0msrc_corners\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrows\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mcols\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrows\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 163\u001b[0m \u001b[0mdst_corners\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msrc_corners\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdouble\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 164\u001b[0m \u001b[0;31m# take into account that 0th pixel is at position (0.5, 0.5)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 89 | "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for -: 'NoneType' and 'int'" 90 | ] 91 | } 92 | ], 93 | "source": [ 94 | "j = im_to_binary(files[0], None)\n", 95 | "for f in files[1:]:\n", 96 | " a = im_to_binary(f, None)\n", 97 | " j &= a\n", 98 | "io.imshow(img_as_ubyte(j))" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 5, 104 | "id": "measured-baking", 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "io.imsave('and.jpeg', img_as_ubyte(j))" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 6, 114 | "id": "resident-product", 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "name": "stderr", 119 | "output_type": "stream", 120 | "text": [ 121 | ":3: FutureWarning: Non RGB image conversion is now deprecated. For RGBA images, please use rgb2gray(rgba2rgb(rgb)) instead. In version 0.19, a ValueError will be raised if input image last dimension length is not 3.\n", 122 | " i = rgb2gray(i)\n" 123 | ] 124 | }, 125 | { 126 | "data": { 127 | "text/plain": [ 128 | "" 129 | ] 130 | }, 131 | "execution_count": 6, 132 | "metadata": {}, 133 | "output_type": "execute_result" 134 | }, 135 | { 136 | "data": { 137 | "image/png": "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\n", 138 | "text/plain": [ 139 | "
" 140 | ] 141 | }, 142 | "metadata": { 143 | "needs_background": "light" 144 | }, 145 | "output_type": "display_data" 146 | } 147 | ], 148 | "source": [ 149 | "j = im_to_binary(files[0])\n", 150 | "for f in files[1:]:\n", 151 | " a = im_to_binary(f)\n", 152 | " j |= a\n", 153 | "io.imshow(img_as_ubyte(j))" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 7, 159 | "id": "broken-rotation", 160 | "metadata": {}, 161 | "outputs": [ 162 | { 163 | "name": "stdout", 164 | "output_type": "stream", 165 | "text": [ 166 | "['./imgs/codes/snapcode.png', './imgs/codes/snapcode 15.png', './imgs/codes/snapcode 14.png', './imgs/codes/snapcode 13.png', './imgs/codes/snapcode 12.png', './imgs/codes/snapcode 9.png', './imgs/codes/snapcode 10.png', './imgs/codes/snapcode 11.png', './imgs/codes/snapcode 8.png', './imgs/codes/snapcode 5.png', './imgs/codes/snapcode 4.png', './imgs/codes/snapcode 6.png', './imgs/codes/snapcode 7.png', './imgs/codes/snapcode 3.png', './imgs/codes/snapcode 2.png']\n" 167 | ] 168 | } 169 | ], 170 | "source": [ 171 | "folder = \"./imgs/codes\"\n", 172 | "\n", 173 | "files = [os.path.join(folder, i) for i in os.listdir(folder) if not i == '.DS_Store']\n", 174 | "print(files)\n" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 8, 180 | "id": "collectible-senator", 181 | "metadata": {}, 182 | "outputs": [ 183 | { 184 | "name": "stderr", 185 | "output_type": "stream", 186 | "text": [ 187 | ":3: FutureWarning: Non RGB image conversion is now deprecated. For RGBA images, please use rgb2gray(rgba2rgb(rgb)) instead. In version 0.19, a ValueError will be raised if input image last dimension length is not 3.\n", 188 | " i = rgb2gray(i)\n" 189 | ] 190 | }, 191 | { 192 | "data": { 193 | "text/plain": [ 194 | "" 195 | ] 196 | }, 197 | "execution_count": 8, 198 | "metadata": {}, 199 | "output_type": "execute_result" 200 | }, 201 | { 202 | "data": { 203 | "image/png": "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\n", 204 | "text/plain": [ 205 | "
" 206 | ] 207 | }, 208 | "metadata": { 209 | "needs_background": "light" 210 | }, 211 | "output_type": "display_data" 212 | } 213 | ], 214 | "source": [ 215 | "j = im_to_binary(files[0])\n", 216 | "for f in files[1:]:\n", 217 | " a = im_to_binary(f)\n", 218 | " j &= a\n", 219 | "io.imshow(img_as_ubyte(j))" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 9, 225 | "id": "owned-array", 226 | "metadata": { 227 | "scrolled": true 228 | }, 229 | "outputs": [ 230 | { 231 | "name": "stderr", 232 | "output_type": "stream", 233 | "text": [ 234 | ":3: FutureWarning: Non RGB image conversion is now deprecated. For RGBA images, please use rgb2gray(rgba2rgb(rgb)) instead. In version 0.19, a ValueError will be raised if input image last dimension length is not 3.\n", 235 | " i = rgb2gray(i)\n" 236 | ] 237 | }, 238 | { 239 | "data": { 240 | "text/plain": [ 241 | "" 242 | ] 243 | }, 244 | "execution_count": 9, 245 | "metadata": {}, 246 | "output_type": "execute_result" 247 | }, 248 | { 249 | "data": { 250 | "image/png": "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\n", 251 | "text/plain": [ 252 | "
" 253 | ] 254 | }, 255 | "metadata": { 256 | "needs_background": "light" 257 | }, 258 | "output_type": "display_data" 259 | } 260 | ], 261 | "source": [ 262 | "j = im_to_binary(files[0])\n", 263 | "for f in files[1:]:\n", 264 | " a = im_to_binary(f)\n", 265 | " j |= a\n", 266 | "io.imshow(img_as_ubyte(j))" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": null, 272 | "id": "anonymous-bishop", 273 | "metadata": {}, 274 | "outputs": [], 275 | "source": [] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 10, 280 | "id": "streaming-company", 281 | "metadata": {}, 282 | "outputs": [ 283 | { 284 | "name": "stdout", 285 | "output_type": "stream", 286 | "text": [ 287 | "['./imgs/codes/snapcode.png', './imgs/codes/snapcode 15.png', './imgs/codes/snapcode 14.png', './imgs/codes/snapcode 13.png', './imgs/codes/snapcode 12.png', './imgs/codes/snapcode 9.png', './imgs/codes/snapcode 10.png', './imgs/codes/snapcode 11.png', './imgs/codes/snapcode 8.png', './imgs/codes/snapcode 5.png', './imgs/codes/snapcode 4.png', './imgs/codes/snapcode 6.png', './imgs/codes/snapcode 7.png', './imgs/codes/snapcode 3.png', './imgs/codes/snapcode 2.png']\n" 288 | ] 289 | } 290 | ], 291 | "source": [ 292 | "folder = \"./imgs/codes\"\n", 293 | "\n", 294 | "files = [os.path.join(folder, i) for i in os.listdir(folder) if not i == '.DS_Store']\n", 295 | "print(files)\n" 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": 11, 301 | "id": "conscious-waters", 302 | "metadata": {}, 303 | "outputs": [ 304 | { 305 | "name": "stderr", 306 | "output_type": "stream", 307 | "text": [ 308 | ":3: FutureWarning: Non RGB image conversion is now deprecated. For RGBA images, please use rgb2gray(rgba2rgb(rgb)) instead. In version 0.19, a ValueError will be raised if input image last dimension length is not 3.\n", 309 | " i = rgb2gray(i)\n" 310 | ] 311 | }, 312 | { 313 | "data": { 314 | "text/plain": [ 315 | "" 316 | ] 317 | }, 318 | "execution_count": 11, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | }, 322 | { 323 | "data": { 324 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAR0AAAEYCAYAAABhpyLIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAAaiElEQVR4nO2db+xlRXnHP09ZgYop/9oQ3N0UGjcaYmKhmxZC0zSiKVIjvCAWY+vGbLNvbMU/iYX2le9qYkRMGtKN1KAx/imSsiFGa4G3UneLQWFFVq2wGxC0gK02VeLTF3d+evlx7++eOWfmzMw530/yy++euc899zkzz3zvnDnznGPujhBCjMWvlXZACDEvJDpCiFGR6AghRkWiI4QYFYmOEGJUJDpCiFHJIjpmdrWZPWpmJ8zsphzfIYRoE0u9TsfMTgO+DbwROAl8DXibuz+S9IuEEE2SY6Tz+8AJd/+uu/8M+CxwbYbvEUI0yK4M+9wNPLG0fRL4g+1GZnYIOBQ2fy+DH0KIsvzQ3X9re2EO0emEux8GDgOYmXIxhJge319VmOP06hSwd2l7TygTQogsovM1YJ+ZXWxmpwM3AEcyfI8QokGSn165+wtm9lfAl4HTgH9y94dTf48Qok2SXzLv5YTmdISYIsfcff/2Qq1IFkKMikRHCDEqxS6Z10QNp5hCpMbMSruwktmKjoRGTJ3lGK9JgGYnOhIbMUe24r4G8ZmF6EhohFhQg/hMfiJZgiPES3H3Yn1jsiMdiY0Qmykx8pmk6KQSnFUNsdO+x7avyZdY+5p8ibVvxZcY3H004ZnU6VXKIeO6BqipvCZfYstr8iW2vDZfUonFWKdckxGdMU+nxp6E2+n7Yn1p2fehpKyr2n0fQu6+NAnR0fyNEGnJ2aeaFx0JjhB5yNW3mhedXOxU4TmFbtW+Y32Zqu9DyV2PNfleM02LTu7KjgmsFOWlOoV8zysupXxPQY79N3vJfCx1j/meVMFYwr4mX2Lt5UteUl9Ob3qkI4RojyZFp7VzWCFaJ2Wfa050JDhCtE2zczpD2Do/7SpgMfbL574x9jl8ibWX72Xsa/N9HanmdmYlOtsrbFNjpLDPue/c9jX5Emvfgi+x9rl9H4umTq9qTnWIzaNJ9b05v1O+x5E79yr2e3OQog82JTpDUP5SP/uhtJy/JN/z0IzolB4SCiEWDO2LzYjOUCRaIiUtx1Np32cjOjtRU95NCykGJXyJpYV0h1S+lEiPGEITotNKIG5/z339TZFWvVdKXFa9V5MvO9m3Xo9j+r5TPMYyZD+zumQO9eXGtJrXU5MvsfY1+RJrn9uXMWhipCOEmA4SHSHEqEh0hBCjMrs5nVhiH/mR6xEhY/gSkwM0pi+x9jX5ssm+Jl/62PdBI50diH38SIx9Tl9i7Vf5vtOjTXL6Emvfuu+rymryPQcSnTXU0DhdyCl0seTuFDlJ4UtO33PXY6o8sC5IdBogZcPXJJhjo3pcUNp3iY4QYlQkOj0Ye8FV7CrVvvvKQUrfh5KyrmpcdNeV0r5LdNZQKu8mBTXlDMUyRd9byL0aM34lOjsQm7sSk0fTx5fl/fXxpWTOUMu+1+pLrH3J+F1G63Q2UNvpS015Oi3nGMmXNPZ92DjSMbO9Zna/mT1iZg+b2Y2h/Dwz+4qZPRb+nxvKzcw+ZmYnzOwhM7ss90EIIdqhy+nVC8D73f0S4HLgXWZ2CXATcK+77wPuDdsAbwL2hb9DwG3JvRZCNMtG0XH3J939P8Lr/waOA7uBa4E7gtkdwHXh9bXAJ33BV4FzzOzC1I4LIdokak7HzC4CLgUeAC5w9yfDW08BF4TXu4Enlj52MpQ9SQZWLXRKlesydN+57Utf+pwLc4mZ2H33pfPVKzN7BfAF4D3u/uPl93zhWZR3ZnbIzI6a2dGYz23bx+Dy3MvFc5aXXlk6B4bmUo1Rvo6cvg+hk+iY2ctYCM6n3f2uUPyDrdOm8P/pUH4K2Lv08T2h7EW4+2F33+/u+/s6H0OLiXFdvk/Ck4+a6r3l+N1Ol6tXBtwOHHf3jyy9dQQ4EF4fAO5eKn9HuIp1OfD80mmYEILyHb8kXeZ0rgT+AviGmX09lP0t8PfA583sIPB94K3hvS8C1wAngJ8C70zpsBBTwD3Nc8FbxGqYjDSzHZ1Y5+NOjbbqM+vsY2xrs6+h/abMXGImdt+bPhM4tmr6pOk0iNh8kRQrP2srF+NTW1uXiOshNJ8GMacl5xKe8ampTWvyZQjNi46oH50aimUkOiIJfSZF+8wjiPaR6Ihe5L7yotXX00WiI6IofeN0iU/7NC86MfkisXMLKexT7bskNa0nWfallbpKle9UU/wOoelL5jnzRUo9wqO2Dl6TP9upzb+acqxiqS73agqkzEWpKdBz0dIxtuRrX1LGaOn6av70SqSldED2RXM+7TAb0ZlzrktXUtXPkI4/1Aczk/BsoHT9TPL0KsVKzNi78qeiVEAM6exbTxnY9LSBsfZV6selVFzExm9pmhadFGKRyj5FeUuCk0pkun5PLKUmmWuKmVhfxorJ5k+vaspHqTXXZR19xaYEW9/bZ0J1bJ9ripkaY7LpkY4Yl9IiueVDrB+ay6uL5kc6oh8xHbEGsdlO35GPKI9GOjOkdcFZpqt/Eqd6mMRIJ3ZpfOyajhj7Fpfpr6JG39fRdTlErZfT5xa/zY90tgfbppWYy+9vusLRx76rLzVTY8fcRKsjnjnGb9OikzN3pVTuVU66+NKi4GzRmu9zjd+mRSeGlJVXk5B0ZeqCs0XsKUQrTCl+ZyM6Yj5MVXimwmxEJ+WveGsjgrmMcpaZ2vGkpHTdNC06OR/hUeNKzj7MUXC6UutoJ3d6T9d99NlPF5oWHXhppWxqnFj7TZ8fYl8Dtfs3hNqPrU88jh2/OZjEOh3lU4l1bFrDU8PanbnFb/MjHbGeTacPpTubmCcSHTF5JK51IdGZKeqIv6LWCeWpMok5nZy0+tA3dSTRhzHiXSOdHUixvFzUQSs/FiUZK94lOmuo+REeQqRmzJiW6MwQ/eqLkkh0hECj1zGR6PRAIwUh+iPRWUPLwqJfbRGLcq8qYXuuSgu5VEL0RblXFSGhmQZd76U8Z5R7JYSYHBIdIcSodBYdMzvNzB40s3vC9sVm9oCZnTCzz5nZ6aH8jLB9Irx/USbfhRANEjPSuRE4vrT9IeAWd38V8CxwMJQfBJ4N5bcEuybZemTH8p8QJckZk2PFeyfRMbM9wJ8CHw/bBrweuDOY3AFcF15fG7YJ719lE+qtEzoU0Rg5Y6/GR9B8FPgA8IuwfT7wnLu/ELZPArvD693AEwDh/eeDfVMo90rUxJTicaPomNmbgafd/VjKLzazQ2Z21MyOptyvEKJuuqzTuRJ4i5ldA5wJ/AZwK3COme0Ko5k9wKlgfwrYC5w0s13A2cCPtu/U3Q8DhwHMTAthhJgJG0c67n6zu+9x94uAG4D73P3twP3A9cHsAHB3eH0kbBPev88bXF0X+8iPsVg12afJ7jTUXLe1xmMfhqzT+RvgfWZ2gsWcze2h/Hbg/FD+PuCmYS7WRakGLh30YkHJdsgZe2PmXlkNKrnp9KoGH0uSOsjnXJ8p63LO9Qid6vKYu+/fXqgVyZWj0U29qG36IdGpGAV1/aiN4pHoVIqCuR3UVnFIdIQQo9L8/XRW/cqsm+Bb94uUyn5MYn0W3eqmb72O8Uz03PEb05eG0PRIJ2e+SMnOO+S7t+5uWIMwtkKXOqu5PlM8r6rG3KvmSZm7Uno00bUDSIBezKrbcbZSN6mzyUvS/OmV6EYrnSs3Q+pBtztNw2xGOup0Qiwo3RcmKTqxlbrKvtXze5GPlnKvUvSBXDQtOinEIndj5kBD/HkylXhvfk4nt6KXEBnNHdRHLe0xhXhveqQzZ2rpBHNgyPoe8VIkOg2j213kR/WbHolOpcT8cqpjpCdG0DXKiaP5OR14cafrEgAx9rH7TknM3M6WnTrAcGoX8ZzxO0a8Nz/S2R4gm1Yex9pv+nxuYhu+9g5TM33ad0yRzx2/MfseQtOikypfJEXuSk76CE9N/rdAn/qqZVSp3KtKaT13pU+AS3g201egxxac1uN3mUnM6cyFrUCPCRrN9aymb8dTPQ5nNiOdlMFSOvA06hmf0hnpU4rfpkUn1WMzak132Ina/auZmieL+5Az90o38VrBqnuk7GQba7/p8yWpzZ8pUlP95o7fmH0PYRJzOjnzS2oKunUoVys9Nbd7zvhV7pXoTM2dpDVUl3mR6IjZEbOKV6RHojMR1FFEKzQ/p7O9s8X+iqW2r5VW/S7FGI+U6cMU4r3pkU7s8u/c9qWo0afaqVFQNjGVeG9adNaRO/eqpk6uG0zlo5V2zpl7lYNJis4qagogUQdzFePSfWE2ojNFNMrJT+kOOkVmIzpTyl0BdYZUxN7YqhRTit+mRWfOuVddmMIx1EINwrOO1nKvmr9k3vqS8Fh03970dE0jKX0ZfQqPn4HGRzpzo+Zf29bp2uHUBsOR6DRCTLBrlNMPCc84SHQaQIJTHxKe/kh0KkeCMy563lh+mp9IXtXwOwVOjH3svlMytbvbtUTNzxvLGb9jxXvTI53Yx2ak+GUa49dNglOeGp83ljN+q3sEjZmdY2Z3mtm3zOy4mV1hZueZ2VfM7LHw/9xga2b2MTM7YWYPmdllyb3uQe7EuBTU/rC3uVHT88ZaiN+udB3p3Ap8yd1fA7wOOA7cBNzr7vuAe8M2wJuAfeHvEHBbUo8nSCvPXpojevJGejaKjpmdDfwRcDuAu//M3Z8DrgXuCGZ3ANeF19cCn/QFXwXOMbMLE/s9CYb8MkpwxqOv8Eh8VtNlpHMx8AzwCTN70Mw+bmZnARe4+5PB5inggvB6N/DE0udPhrIXYWaHzOyomR3t7353Yu6C38c+liEBKcEZn75P3kglPrXF7xC6iM4u4DLgNne/FPgJvzqVAsAXRxF1JO5+2N33u/v+mM9t28fg8hJLxYeMbkoHzNzpW/+5haerfYo+M5QuonMSOOnuD4TtO1mI0A+2TpvC/6fD+6eAvUuf3xPKsrDVEZf/YuxT7rsLOp1qn5KjntbifRUbRcfdnwKeMLNXh6KrgEeAI8CBUHYAuDu8PgK8I1zFuhx4fuk0bNb0nSyW4NSJ2qUfXRcH/jXwaTM7Hfgu8E4WgvV5MzsIfB94a7D9InANcAL4abCdPbo6NU222iimfUtnq5fGajh4M9vRiRp8HIrSGebBnG490uFYj62as20+DQJefPBdGrOvfc5AmUIQin4jn1hi4jF33+hD02kQ8NLG3bQSc4i91l6IrmzqsH3iKDYeV8V6rH0OmhadVPkiscvIhRhKylFEivitLvdqCqSsvBwNIZGbFqnbs/b4jWESczpTYezbJIj0lO7QLTCbkU7pjhx7cygFb1vEtFlLsZiDSYpOzuXiffbfl61AlgDVyZjtkzL3Knb/qWladFKIRe7GTPVZCVB5ltugRDpLa/G+jubndHIreupK94hbYa5Dcz/jkkroU7RXa/G+iqZHOq2SqmE18slPquxw/UD8ColOIRSI9VPidhRzoPnTq9YZY9m8GB+JzXomITo580vGyl0ZIj5zz1quib732Yn5fI3xG0PzorMqX2RdZa1bLt7VftMEbqz9KpZtNfppg5R3E6wtfkvdObBaasq9yiEQue/gJtazqT1ztk1N8avcqwG0nrvSZRitq1nD6VKHJX4EWo/fZZo/vRIvRTcMezGlO5l4MbMRnRSL8pb3NRW218kUji2nyJSqnynFb9OnV+sqL3fuVU5f+nxHSlo9RWvx9HJu8btF06IDL62UTbklQ+w3TRzG7LsvYyeb1s6Yfo7RnrnjsXT8wkROr2rKRxlDFFIOtTdRc57XmKKY8/hrikflXom1jC0CNY16xh6F1Si4LTOJkc5cGTuFovSoR0IzDSQ6EyCmg6TouCXER8mX06F50Ym95JvTflXHiLEfaz5okx9dGUN8hohNLSOylDGTmzFisuk5nXXLv2OWdO8U1DH2KcpLzZsMXc6f+nJ1irvz1SI468r6lOdkXX3n8KX5kU4KViW2bRKjXEFdMmM8xRzR0JHkEEqfPtU02V4zsxEdBUR3Uk5Qj1HvpcVGxNH06ZXIS+2dWRn4bTIb0YlZiTlkX1Oj1o5do0+iG02LTmy+SEyOSm3lpanh3j41+LATLcfAmL40P6fT8hLyWjvPJsZelNhSPbUcA2P50rzoiHIsB2lqAaqpM4q0SHREEmKWHHT5vJguEh2RBYmIWEfTE8m1ojVBIpY5xUzzI52h+U472Q/Zd5e8pJy+izTkbqOcMVNrvDQ90smZ05IzxypluRif2mIgRVyPSdOiE0NsYmfffeUgpe+iOzXVe8oYLR0zsxEdIWqidMcvSSfRMbP3mtnDZvZNM/uMmZ1pZheb2QNmdsLMPmdmpwfbM8L2ifD+RVmPQIgGqWFupRQbRcfMdgPvBva7+2uB04AbgA8Bt7j7q4BngYPhIweBZ0P5LcGuOLG5VylztYZSky9zoqZ6bzl+t9P19GoX8Otmtgt4OfAk8HrgzvD+HcB14fW1YZvw/lWWaSyZM/cq53emKi8dPHOghXy9ddQaMxsvmbv7KTP7MPA48L/AvwLHgOfc/YVgdhLYHV7vBp4In33BzJ4Hzgd+uLxfMzsEHBp6AHPKvaohYOaIYiYtXU6vzmUxerkYeCVwFnD10C9298Puvt/d9w/dlxCiHbqcXr0B+J67P+PuPwfuAq4EzgmnWwB7gFPh9SlgL0B4/2zgR0m9FkI0SxfReRy43MxeHuZmrgIeAe4Hrg82B4C7w+sjYZvw/n1e4xhPCFEE66IHZvZB4M+AF4AHgb9kMXfzWeC8UPbn7v5/ZnYm8CngUuC/gBvc/bsb9r+jEzE39+54PFXse4h9Tb7E2tfkS6x9aV+G3Pg+ty8rOLZq+qST6ORmiOgMzUXJbV+TL7H2NfkSa9+CL7H2Lfi+jZWi0/SK5FR5SqvsUy07L5FiId/r8j1FeWxaQ6l67ELTohNDysqrKe9GeWPdmVL+0hBK+z4b0RFC1MFsRKeGuau+pPS95XoYiupxQWnfJyk6uZeL52y0lpe6p6jHVnzvuo9U5K7HMeu9adHJHeSxeTdD83Rq8n3d8eT2Jda+dd9XlbXg+xCav11pbbkrMfY1+RJrX5MvsfbyJZ19H5oe6Qgh2kOiI4QYFYmOEGJUmp/T6cNUcl1K+j6mL7H2LfkSa5/blzFoYqSTagWlmb1kXymXl6/a907Ly8f0JdZ+k+9j+rKTfQv1uJNtLfEYy5D9NCE6uSmR61LKl5Z9r92XUrmAOesxB7MRnZobQbRHy/FU2vdmRKd0RQkhFgzti82IzlBSpjWMPSEn39OQsq5q932sffVhNqITS6oALSEK8r0u31OVx3xvLmFJccbR1CVzMxtUmVuf3aq4TfvqY9/1EuUYvsTay/cy9rX4PhZNiU4qlEtTvy+x9jX5Emtfky9j0NzplSaUhShDqr7XnOiAhEeIsUnZ55oUHSFEuzQ7pzN0Ujnme5bZ6TtX/RrktE+Zp1OTL7H2NfleWwykIPWZRdMjndynWbE5QCnKU/gSa5+ivGTu1dDy2tIjUvmeghz7b1p0chIbiDm/N3eHTkXtOUOt5LB1/b4xvjcHzYtOaxUuRCvk6lvNiw5IeIRITc4+NQnRgXGFp6a8m9oXirWcv9Sy70PI3ZcmIzqQ9iZFufNoUpTX5EtseU2+xJbX5MtO5bGk7D870ewl851IdTm9tuXpLS+tl+9l7Lsy5pnCJEUH6ktyE6JGSsyHTur0ahWaZBZiNaX6xmRHOsto1CPEghp+hGchOlt0vW+JEFOjBrHZYlais4wESEydmoRmmdmKzjK1No4QU2TyE8lCiLqQ6AghRkWiI4QYFYmOEGJUJDpCiFGR6AghRkWiI4QYlVrW6fwP8GhpJwbym8APSzsxkCkcA0zjOKZwDL+9qrAW0XnU3feXdmIIZnZUx1AHUziOKRzDOnR6JYQYFYmOEGJUahGdw6UdSICOoR6mcBxTOIaVmDKshRBjUstIRwgxEyQ6QohRKS46Zna1mT1qZifM7KbS/qzDzPaa2f1m9oiZPWxmN4by88zsK2b2WPh/big3M/tYOK6HzOyyskewwMxOM7MHzeyesH2xmT0Q/PycmZ0eys8I2yfC+xcVdXwJMzvHzO40s2+Z2XEzu6LBdnhviKNvmtlnzOzMFtuiD0VFx8xOA/4BeBNwCfA2M7ukpE878ALwfne/BLgceFfw9SbgXnffB9wbtmFxTPvC3yHgtvFdXsmNwPGl7Q8Bt7j7q4BngYOh/CDwbCi/JdjVwq3Al9z9NcDrWBxPM+1gZruBdwP73f21wGnADbTZFvG4e7E/4Argy0vbNwM3l/Qpwve7gTeyWEl9YSi7kMVCR4B/BN62ZP9Lu4I+72HRIV8P3AMYi1Wvu7a3B/Bl4Irwelewswrq/Wzge9t9aawddgNPAOeFur0H+JPW2qLvX+nTq63K3+JkKKuaMLy9FHgAuMDdnwxvPQVcEF7XeGwfBT4A/CJsnw885+4vhO1lH3/pf3j/+WBfmouBZ4BPhNPEj5vZWTTUDu5+Cvgw8DjwJIu6PUZ7bdGL0qLTHGb2CuALwHvc/cfL7/nip6jKNQhm9mbgaXc/VtqXgewCLgNuc/dLgZ/wq1MpoO52AAjzTdeyENBXAmcBVxd1akRKi84pYO/S9p5QViVm9jIWgvNpd78rFP/AzC4M718IPB3Kazu2K4G3mNl/Ap9lcYp1K3COmW3l4C37+Ev/w/tnAz8a0+E1nAROuvsDYftOFiLUSjsAvAH4nrs/4+4/B+5i0T6ttUUvSovO14B9Ydb+dBaTaUcK+7QSWzwy4nbguLt/ZOmtI8CB8PoAi7merfJ3hKsnlwPPLw3/R8fdb3b3Pe5+EYt6vs/d3w7cD1wfzLb7v3Vc1wf74qMHd38KeMLMXh2KrgIeoZF2CDwOXG5mLw9xtXUMTbVFb0pPKgHXAN8GvgP8XWl/dvDzD1kM2R8Cvh7+rmFxbn0v8Bjwb8B5wd5YXJn7DvANFlcqih9H8O2PgXvC698B/h04AfwzcEYoPzNsnwjv/05pv5f8/13gaGiLfwHOba0dgA8C3wK+CXwKOKPFtujzpzQIIcSolD69EkLMDImOEGJUJDpCiFGR6AghRkWiI4QYFYmOEGJUJDpCiFH5f7+GATC9CvaRAAAAAElFTkSuQmCC\n", 325 | "text/plain": [ 326 | "
" 327 | ] 328 | }, 329 | "metadata": { 330 | "needs_background": "light" 331 | }, 332 | "output_type": "display_data" 333 | } 334 | ], 335 | "source": [ 336 | "j = im_to_binary(files[0])\n", 337 | "for f in files[1:]:\n", 338 | " a = im_to_binary(f)\n", 339 | " j &= a\n", 340 | "io.imshow(img_as_ubyte(j))" 341 | ] 342 | }, 343 | { 344 | "cell_type": "code", 345 | "execution_count": 12, 346 | "id": "announced-authority", 347 | "metadata": { 348 | "scrolled": true 349 | }, 350 | "outputs": [ 351 | { 352 | "name": "stderr", 353 | "output_type": "stream", 354 | "text": [ 355 | ":3: FutureWarning: Non RGB image conversion is now deprecated. For RGBA images, please use rgb2gray(rgba2rgb(rgb)) instead. In version 0.19, a ValueError will be raised if input image last dimension length is not 3.\n", 356 | " i = rgb2gray(i)\n" 357 | ] 358 | }, 359 | { 360 | "data": { 361 | "text/plain": [ 362 | "" 363 | ] 364 | }, 365 | "execution_count": 12, 366 | "metadata": {}, 367 | "output_type": "execute_result" 368 | }, 369 | { 370 | "data": { 371 | "image/png": "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\n", 372 | "text/plain": [ 373 | "
" 374 | ] 375 | }, 376 | "metadata": { 377 | "needs_background": "light" 378 | }, 379 | "output_type": "display_data" 380 | } 381 | ], 382 | "source": [ 383 | "j = im_to_binary(files[0])\n", 384 | "for f in files[1:]:\n", 385 | " a = im_to_binary(f)\n", 386 | " j |= a\n", 387 | "io.imshow(img_as_ubyte(j))" 388 | ] 389 | }, 390 | { 391 | "cell_type": "markdown", 392 | "id": "corporate-classic", 393 | "metadata": {}, 394 | "source": [ 395 | "## Cropped people" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 16, 401 | "id": "controlling-petite", 402 | "metadata": {}, 403 | "outputs": [ 404 | { 405 | "name": "stdout", 406 | "output_type": "stream", 407 | "text": [ 408 | "['./imgs/people/cropped/FEIu0F9XMAcFnnC.jpeg', './imgs/people/cropped/FEK1L9cXoAgulGK.png', './imgs/people/cropped/person_E_1SliPVkAU9LRZ.jpeg', './imgs/people/cropped/person_FD9XmqWXIAYvYz6.jpeg', './imgs/people/cropped/FEJNLkmXIAMnJQP.jpeg', './imgs/people/cropped/person_FA4M9uIWQBQ7Y09.jpeg', './imgs/people/cropped/person_E_y5sW7UYAUhvVJ.jpeg', './imgs/people/cropped/personFD_8QyqXwAALMdW.jpeg', './imgs/people/cropped/FECYsfjXwAIEYmJ.png', './imgs/people/cropped/person_66c49c2d2e645826cd079524d1109bbf.jpeg', './imgs/people/cropped/FEJjiv8XwAInJVO.jpeg']\n" 409 | ] 410 | } 411 | ], 412 | "source": [ 413 | "folder = \"./imgs/people/cropped\"\n", 414 | "\n", 415 | "files = [os.path.join(folder, i) for i in os.listdir(folder) if not i == '.DS_Store']\n", 416 | "print(files)\n" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": 17, 422 | "id": "intensive-relief", 423 | "metadata": {}, 424 | "outputs": [ 425 | { 426 | "data": { 427 | "text/plain": [ 428 | "" 429 | ] 430 | }, 431 | "execution_count": 17, 432 | "metadata": {}, 433 | "output_type": "execute_result" 434 | }, 435 | { 436 | "data": { 437 | "image/png": "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\n", 438 | "text/plain": [ 439 | "
" 440 | ] 441 | }, 442 | "metadata": { 443 | "needs_background": "light" 444 | }, 445 | "output_type": "display_data" 446 | } 447 | ], 448 | "source": [ 449 | "j = im_to_binary(files[0])\n", 450 | "for f in files[1:]:\n", 451 | " a = im_to_binary(f)\n", 452 | " j &= a\n", 453 | "io.imshow(img_as_ubyte(j))" 454 | ] 455 | }, 456 | { 457 | "cell_type": "code", 458 | "execution_count": 18, 459 | "id": "personal-color", 460 | "metadata": { 461 | "scrolled": false 462 | }, 463 | "outputs": [ 464 | { 465 | "data": { 466 | "text/plain": [ 467 | "" 468 | ] 469 | }, 470 | "execution_count": 18, 471 | "metadata": {}, 472 | "output_type": "execute_result" 473 | }, 474 | { 475 | "data": { 476 | "image/png": "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\n", 477 | "text/plain": [ 478 | "
" 479 | ] 480 | }, 481 | "metadata": { 482 | "needs_background": "light" 483 | }, 484 | "output_type": "display_data" 485 | } 486 | ], 487 | "source": [ 488 | "j = im_to_binary(files[0])\n", 489 | "for f in files[1:]:\n", 490 | " a = im_to_binary(f)\n", 491 | " j |= a\n", 492 | "io.imshow(img_as_ubyte(j))" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": null, 498 | "id": "attached-funds", 499 | "metadata": {}, 500 | "outputs": [], 501 | "source": [] 502 | }, 503 | { 504 | "cell_type": "code", 505 | "execution_count": null, 506 | "id": "aggregate-mongolia", 507 | "metadata": {}, 508 | "outputs": [], 509 | "source": [] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "execution_count": null, 514 | "id": "material-support", 515 | "metadata": {}, 516 | "outputs": [], 517 | "source": [] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": null, 522 | "id": "smart-norway", 523 | "metadata": {}, 524 | "outputs": [], 525 | "source": [] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "execution_count": null, 530 | "id": "corresponding-girlfriend", 531 | "metadata": {}, 532 | "outputs": [], 533 | "source": [] 534 | } 535 | ], 536 | "metadata": { 537 | "kernelspec": { 538 | "display_name": "Python 3", 539 | "language": "python", 540 | "name": "python3" 541 | }, 542 | "language_info": { 543 | "codemirror_mode": { 544 | "name": "ipython", 545 | "version": 3 546 | }, 547 | "file_extension": ".py", 548 | "mimetype": "text/x-python", 549 | "name": "python", 550 | "nbconvert_exporter": "python", 551 | "pygments_lexer": "ipython3", 552 | "version": "3.9.7" 553 | } 554 | }, 555 | "nbformat": 4, 556 | "nbformat_minor": 5 557 | } 558 | --------------------------------------------------------------------------------