{"id":17101292,"url":"https://github.com/hackerb9/passportpix","last_synced_at":"2025-04-13T00:02:39.795Z","repository":{"id":40680571,"uuid":"131249935","full_name":"hackerb9/passportpix","owner":"hackerb9","description":"Take a passport photo of proper dimensions using computer vision","archived":false,"fork":false,"pushed_at":"2023-08-14T02:52:41.000Z","size":3384,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-26T18:02:42.300Z","etag":null,"topics":["camera","face-detection","image-processing","opencv-python","passport","photo"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hackerb9.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-27T05:33:58.000Z","updated_at":"2025-03-11T10:31:17.000Z","dependencies_parsed_at":"2022-09-01T06:41:53.835Z","dependency_job_id":null,"html_url":"https://github.com/hackerb9/passportpix","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackerb9%2Fpassportpix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackerb9%2Fpassportpix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackerb9%2Fpassportpix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackerb9%2Fpassportpix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hackerb9","download_url":"https://codeload.github.com/hackerb9/passportpix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647225,"owners_count":21139084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["camera","face-detection","image-processing","opencv-python","passport","photo"],"created_at":"2024-10-14T15:24:40.252Z","updated_at":"2025-04-13T00:02:39.763Z","avatar_url":"https://github.com/hackerb9.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# passportpix\n\n\u003cimg src=\"./US-examples/good/img_good_12.jpg\" align=\"right\" width=\"25%\"\u003e\n\nTake a passport photo of precisely the proper dimensions using\ncomputer vision to pan and zoom on the face.\n\nDefaults to US Passport requirements, but can be modified for others.\n\nShows live camera view. Automatically centers and zooms image to be\nprecisely correct for passport photos. Hit spacebar to snap the photo\nto \"passport.jpg\" and \u003ckbd\u003eq\u003c/kbd\u003e to quit.\n\n## How to run\n\n``` bash\napt install python-opencv opencv-data\ngit clone https://github.com/hackerb9/passportpix\ncd passportpix\n./passport.py\n```\n\n## Notes\n\n### Resolution\n\nThe image saved to a file is higher resolution than the preview shown\non screen. The face detection routine is a bit CPU hungry so the image\nis downscaled to fit in a 640x640 square before processing to get a\nbetter frame rate. Likewise, some low-end computers, such as the\nRaspberry Pi, struggle with displaying large images rapidly, so the\ndownscaled image is used for screen display.\n\n### TIP\n\nIf you leave an image viewer, such as `eog passport.jpg`, running\nin the background, you'll see the picture update immediately so you\ncan tell if you like it or not.\n\n### TIP\n\nIf you need a \"portrait\" photo (taller than it is wide), you can\nimprove the image resolution by rotating your camera sideways and edit\nthe `camera_rotation` variable at the top of the file. (Or hit the 'r'\nkey). \n\n## Customization\n\nThe default setup is correct for US Passport photos:\n\n| Variable     | Description                                                              | Setting for US Passport         |\n|--------------|--------------------------------------------------------------------------|---------------------------------|\n| photo_aspect | Ratio of width to height                                                 | 1\u003cbr/\u003e(square)                  |\n| eye_distance | Distance between eyes, expressed as a fraction of the picture width      | 2/12\u003cbr/\u003e(= ⅓\" on a 2\" width)   |\n| eye_height   | Distance of eyes from bottom of picture, as a fraction of picture height | 7/12\u003cbr/\u003e(= 1⅙\" on a 2\" height) |\n\nThese variables are listed at the top of passport.py and can be\nchanged there.\n\n\u003cdetails\u003e\u003csummary\u003eClick to see an example customization\u003c/summary\u003e\n\n### Example customization\n\nIf one need a visa to visit China, the photo requirements as of 2020 are:\n\n| Variable     | Description                                                              | Setting for CN Visa             |\n|--------------|--------------------------------------------------------------------------|---------------------------------|\n| photo_width  | Width of printed photo                                                   | 33                              |\n| photo_height | Height of printed photo                                                  | 48                              |\n| photo_units  | Unit of measurement of width and height                                  | mm                              |\n| photo_aspect | Ratio of width to height                                                 | 33/48                           |\n| eye_height   | Distance of eyes from bottom of picture, as a fraction of picture height | 24/48\u003cbr/\u003e(precisely in middle) |\n| chin_height  | Distance of chin from bottom of picture, as a fraction of picture height | 7/48                            |\n\nSo, one would set:\n\n``` python\n# Setting for Chinese Visa photo\nphoto_width  = 33.0\nphoto_height = 48.0\nphoto_units  = \"mm\"\nphoto_aspect = photo_width/photo_height\neye_height   = 24.0 / 48.0\nchin_height  = 7.0 / 48.0\nuse_chin_height = True\n```\n\nNote that by default `use_chin_height` is False, which causes\n`eye_distance` to be used for calculating the scaling instead of\n`chin_height`. You can also hit the \u003ckbd\u003eTab\u003c/kbd\u003e key to switch\nbetween those two methods.\n\n\u003c/details\u003e\n\n## Current keys\n\n* \u003ckbd\u003eSpace\u003c/kbd\u003e: Save snapshot to passport.jpg\n* \u003ckbd\u003eq\u003c/kbd\u003e or \u003ckbd\u003eEsc\u003c/kbd\u003e: Quit\n* \u003ckbd\u003ef\u003c/kbd\u003e: Toggle fullscreen\n\nLess useful keys:\n* \u003ckbd\u003em\u003c/kbd\u003e: Toggle mirroring\n* \u003ckbd\u003er\u003c/kbd\u003e: Increment camera rotation by 90°\n* \u003ckbd\u003eTab\u003c/kbd\u003e: Toggle between US (eye distance) and Chinese (chin\n  distance) photo requirements. Does not change photo dimensions.\n* \u003ckbd\u003eEnter\u003c/kbd\u003e: Show debugging info, save debugging images\n\n### Experimental keys for resolution\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eClick to see more keys\u003c/b\u003e\u003c/summary\u003e\n\n\u003cblockquote\u003e\n\nThese keys change the downscale resolution which is used for both the\ncomputer vision processing and for display on the screen. They do not\naffect the output resolution in the saved file.\n\n| Key          | Maximum height or width |\n|--------------|-------------------------|\n| \u003ckbd\u003e1\u003c/kbd\u003e | 160                     |\n| \u003ckbd\u003e2\u003c/kbd\u003e | 320                     |\n| \u003ckbd\u003e3\u003c/kbd\u003e | 640 (default)           |\n| \u003ckbd\u003e4\u003c/kbd\u003e | 960                     |\n| \u003ckbd\u003e5\u003c/kbd\u003e | 1280                    |\n| \u003ckbd\u003e0\u003c/kbd\u003e | Native resolution       |\n\nNote that OpenCV's builtin face detection algorithms failed for me on\n160×160 images.\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\n## Current Assumptions\n\n* I assume you always want the highest resolution possible from your camera.\n\n* You'll need to have 'python-opencv' installed. (`apt install python-opencv`) \n\n## Bugs and Future Features.\n\n* Cropped image jitters as eye locations are approximated. Ought to\n  show uncropped camera view either in a second window or alone with a\n  rectangle showing how the image will be cropped.\n\n* OpenCV cannot write the proper DPI to the JPEG file, so it will not\n  print out at the correct size without massaging. This is annoying, but\n  is easy enough to work around that I'm not fixing it before the\n  release.\n\n* You can only take one photo. Every photo you take overwrites the\n  previous 'passport.jpg' file.\n\n* Only the first camera is opened. You can change that by editing\n  `camera_device` at the beginning of the file.\n\n* When recentering the face, especially if it is very close to the\n  camera, there may not be enough picture from the camera to extend all\n  the way to the edge of the final photo. The program should warn about\n  this and give a visual indication of which way to move to fix it.\n\n* If your face is too far away, the camera will zoom in too much,\n  causing a blurry picture. This program ought to detect if height or\n  width is less than 600 and ask the user to step closer.\n\n## Debugging \u0026amp; such\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eClick to see info about debugging\u003c/b\u003e\u003c/summary\u003e\n\u003cblockquote\u003e\n\nMostly reminders to myself.\n\n* To list all resolutions a camera is capable of:\n\n  ```\n  v4l2-ctl --list-formats-ext\n  ```\n\n* OpenCV appears to prefer uncompressed video, even if a camera can\n  provide a higher resolution \u0026 frame rate with compression turned on.\n\n  This may not be a problem. I've added functionality to allow for\n  compression and lower FPS, but even though the nominal resolution\n  was higher, the quality was noticeably worse than simply scaling the\n  uncompressed video. (At least on the cameras I tried). If you want\n  to give it a shot, change the variables `camera_codec='MJPG'` or\n  `camera_fps=15`.\n\n* To print out the current GUI properties and other debugging info,\n  hit \u003ckbd\u003eEnter\u003c/kbd\u003e.\n\n* OpenCV has unnecessarily confusing GUI window properties. In\n  particular, it appears OpenCV was originally written using simple\n  integer Booleans (0 or 1), but someone later came along and decided\n  that was too sloppy and renamed them all. However, instead of using\n  the typical True or False, they came up with new names for truth\n  values for each variable so each has its own nearly-unique way of\n  being used.\n\n  I found this silly and hard to read, so I do not follow that\n  practice. For example, I have replaced the following code:\n\n  ```python\n  isFull = (cv2.getWindowProperty(title, cv2.WND_PROP_FULLSCREEN) == cv2.WINDOW_FULLSCREEN)a\n  cv2.setWindowProperty(title,\n\t\t\tcv2.WND_PROP_FULLSCREEN,\n\t\t\tcv2.WINDOW_NORMAL if isFull else cv2.WINDOW_FULLSCREEN)\n  ```\n\n  with:\n\n  ```python\n  isFull = cv2.getWindowProperty(title, cv2.WND_PROP_FULLSCREEN)\n  cv2.setWindowProperty(title, cv2.WND_PROP_FULLSCREEN, 1 - isFull)\n  ```\n\n* Here are the OpenCV window properties and their official\n  documentation (as of 2023). _(Italics mine.)_\n\n   * `WND_PROP_FULLSCREEN`\u003cbr/\u003e\n       fullscreen property (can be `WINDOW_NORMAL` or `WINDOW_FULLSCREEN`).\u003cbr/\u003e\n       _Boolean `NORMAL` is 0 and `FULLSCREEN` is 1_\n\n   * `WND_PROP_AUTOSIZE`\u003cbr/\u003e\n       autosize property (can be `WINDOW_NORMAL`, 0, or `WINDOW_AUTOSIZE`, 1).\u003cbr/\u003e\n       _Boolean `NORMAL` is 0 and `AUTOSIZE` is 1_\n\t   \n   * `WND_PROP_ASPECT_RATIO`\u003cbr/\u003e\n       window's aspect ration (can be `WINDOW_FREERATIO` or `WINDOW_KEEPRATIO`).\u003cbr/\u003e\n       _Boolean `KEEPRATIO` is 0 and `FREERATIO` is 256_\n\t   \n   * `WND_PROP_OPENGL`\u003cbr/\u003e\n       opengl support.\u003cbr/\u003e\n       _Presumed to be Boolean, but documentation does not specify._\n\t   \n   * `WND_PROP_VISIBLE`\u003cbr/\u003e\n       checks whether the window exists and is visible.\u003cbr/\u003e\n       _Presumed to be Boolean, but documentation does not specify._\n\t   \n   * `WND_PROP_TOPMOST`\u003cbr/\u003e\n       property to toggle normal window being topmost or not. \u003cbr/\u003e\n       _Presumed to be Boolean, but documentation does not specify._\n\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\n## Bonus: Harpy.py\n\nHere is a simple Python script for face detection in live video using\nOpenCV. \u003ca href=\"harpy.py\"\u003eharpy.py\u003c/a\u003e. Short and easy to modify if\nyou want to start another project like this.\n\n\u003cimg src=\"./README.md.d/harpy.py-screenshot2.jpg\"\u003e\n\n\u003cimg src=\"./README.md.d/harpy.py-screenshot3.jpg\"\u003e\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackerb9%2Fpassportpix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhackerb9%2Fpassportpix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackerb9%2Fpassportpix/lists"}