diff --git a/README.md b/README.md index 60c69f7..2c61e22 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ The detected skin tones are then classified into the specified color categories. The library finally generates results to report the detected faces (if any), dominant skin tones and color categories. -*If you find this project helpful, please consider [giving it a star](https://github.com/ChenglongMa/SkinToneClassifier)* ⭐. *It would be a great encouragement for me!* +*If you find this project helpful, please +consider [giving it a star](https://github.com/ChenglongMa/SkinToneClassifier)* ⭐. *It would be a great encouragement +for me!* --- @@ -25,176 +27,35 @@ dominant skin tones and color categories. **Table of Contents** - [Changelogs](#changelogs) - - [v1.1.2](#v112) - - [v1.1.1](#v111) - - [v1.1.0](#v110) - - [v1.0.1](#v101) - - [v1.0.0](#v100) - - [v0.2.0](#v020) + - [v1.1.2](#v112) + - [v1.1.1](#v111) + - [v1.1.0](#v110) + - [v1.0.1](#v101) + - [v1.0.0](#v100) + - [v0.2.0](#v020) - [Citation](#citation) - [Installation](#installation) - - [Install from pip](#install-from-pip) - - [Install from source](#install-from-source) + - [Install from pip](#install-from-pip) + - [Install from source](#install-from-source) - [HOW TO USE](#how-to-use) - - [Quick Start](#quick-start) - - [Interpretation of the table](#interpretation-of-the-table) - - [Detailed Usage](#detailed-usage) - - [Use Cases](#use-cases) - - [1. To process multiple images](#1-to-process-multiple-images) - - [2. To specify color categories](#2-to-specify-color-categories) - - [3. Specify output folder](#3-specify-output-folder) - - [4. Store report images for debugging](#4-store-report-images-for-debugging) - - [5. Specify the types of the input image(s)](#5-specify-the-types-of-the-input-images) - - [6. Convert the `color` images to `black/white` images and then do the classification using `bw` palette](#6-convert-the-color-images-to-blackwhite-images-and-then-do-the-classification-using-bw-palette) - - [7. Tune parameters of face detection](#7-tune-parameters-of-face-detection) - - [8. Multiprocessing settings](#8-multiprocessing-settings) - - [9. Used as a library by importing into other projects](#9-used-as-a-library-by-importing-into-other-projects) + - [Quick Start](#quick-start) + - [Interpretation of the table](#interpretation-of-the-table) + - [Detailed Usage](#detailed-usage) + - [Use Cases](#use-cases) + - [1. To process multiple images](#1-to-process-multiple-images) + - [2. To specify color categories](#2-to-specify-color-categories) + - [3. Specify output folder](#3-specify-output-folder) + - [4. Store report images for debugging](#4-store-report-images-for-debugging) + - [5. Specify the types of the input image(s)](#5-specify-the-types-of-the-input-images) + - [6. Convert the `color` images to `black/white` images and then do the classification using `bw` palette](#6-convert-the-color-images-to-blackwhite-images-and-then-do-the-classification-using-bw-palette) + - [7. Tune parameters of face detection](#7-tune-parameters-of-face-detection) + - [8. Multiprocessing settings](#8-multiprocessing-settings) + - [9. Used as a library by importing into other projects](#9-used-as-a-library-by-importing-into-other-projects) - [Contributing](#contributing) - [Disclaimer](#disclaimer) -# Changelogs - -## v1.1.2 - -In this version, we have made the following changes: - -1. 🐛 **FIX!**: We fixed a bug where the app will crash when using the `-bw` option. - Error message: `cannot reshape array of size 62500 into shape (3)`. -2. 🐛 **FIX!**: We fixed a bug where the app may identify the image type as `color` when using the `-bw` option. - -## v1.1.1 - -In this version, we have made the following changes: - -1. ✨ **NEW!**: We add the `-v` (or `--version`) option to show the version number. -2. ✨ **NEW!**: We add the `-r` (or `--recursive`) option to **enable** recursive search for images. - * For example, `stone -i ./path/to/images/ -r` will search all images in the `./path/to/images/` directory **and its subdirectories**. - * `stone -i ./path/to/images/` will only search images in the `./path/to/images/` directory. -3. 🐛 **FIX!**: We fixed a bug where the app cannot correctly identify the current folder if `-i` option is not specified. - -## v1.1.0 - -
- Click here to show more. - -In this version, we have made the following changes: - -1. ✨ **NEW!**: Now, `stone` can not only be run on **the command line**, but can also be **imported** into other - projects for use. Check [this](#9-used-as-a-library-by-importing-into-other-projects) for more details. - * We expose the `process` and `show` functions in the `stone` package. -2. ✨ **NEW!**: We add `URL` support for the input images. - * Now, you can specify the input image as a URL, e.g., `https://example.com/images/pic.jpg`. Of course, you can mix - the URLs and local filenames. -3. ✨ **NEW!**: We add **recursive search** support for the input images. - * Now, when you specify the input image as a directory, e.g., `./path/to/images/`. - The app will search all images in the directory recursively. -4. 🧬 **CHANGE!**: We change the column header in `result.csv`: - * `prop` => `percent` - * `PERLA` => `tone label` -5. 🐛 **FIX!**: We fixed a bug where the app would not correctly sort files that did not contain numbers in their - filenames. - -
- -## v1.0.1 - -
- Click here to show more. - -1. 👋 **BYE**: We have removed the function to pop up a resulting window when processing a **single** image. - - * It can raise an error when running the app in a **web browser** environment, e.g., Jupyter Notebook or Google - Colab. - * If you want to see the processed image, please use the `-d` option to store the report image in the `./debug` - folder. - -
- -## v1.0.0 - -
- Click here to show more. - -🎉**We have officially released the 1.0.0 version of the library!** In this version, we have made the following changes: - -1. ✨ **NEW!**: We add the `threshold` parameter to control the minimum percentage of required face areas (Defaults to - 0.15). - * In previous versions, the library could incorrectly identify non-face areas as faces, such as shirts, collars, - necks, etc. - In order to improve its accuracy, the new version will further calculate the proportion of skin in the recognized - area - after recognizing the facial area. If it is less than the `threshold` value, the recognition area will be ignored. - (While it's still not perfect, it's an improvement over what it was before.) -2. ✨ **NEW!**: Now, we will back up the previous results if it already exists. - The backup file will be named as `result_bak_.csv`. -3. 🐛 **FIX!**: We fix the bug that the `image_type` option does not work in the previous version. -4. 🐛 **FIX!**: We fix the bug that the library will create an empty `log` folder when checking the help information by - running `stone -h`. - -
- -## v0.2.0 - -
- Click here to show more. - -In this version, we have made the following changes: - -1. ✨ **NEW!**: Now we support skin tone classification for **black and white** images. - * In this case, the app will use different skin tone palettes for color images and black/white images. - * We use a new parameter `-t` or `--image_type` to specify the type of the input image. - It can be `color`, `bw` or `auto`(default). - `auto` will let the app automatically detect whether the input is color or black/white image. - * We use a new parameter `-bw` or `--black_white` to specify whether to convert the input to black/white image. - If so, the app will convert the input to black/white image and then classify the skin tones based on the - black/white palette. - - For example: -
- Processing color image - Processing black/white image -
- -2. ✨ **NEW!**: Now we support **multiprocessing** for processing the images. It will largely speed up the processing. - * The number of processes is set to the number of CPU cores by default. - * You can specify the number of processes by `--n_workers` parameter. -3. 🧬 **CHANGE!**: We add more details in the report image to facilitate the debugging, as shown above. - * We add the face id in the report image. - * We add the effective face or skin area in the report image. In this case, the other areas are blurred. -4. 🧬 **CHANGE!**: Now, we save the report images into different folders based on their `image_type` (color or - black/white) and the number of detected faces. - * For example, if the input image is **color** and there are **2 faces** detected, the report image will be saved - in `./debug/color/faces_2/` folder. - * If the input image is **black/white** and no face has been detected, the report image will be saved - in `./debug/bw/faces_0/` folder. - * You can easily to tune the parameters and rerun the app based on the report images in the corresponding folder. -5. 🐛 **FIX!**: We fix the bug that the app will crash when the input image has dimensionality errors. - * Now, the app won't crash and will report the error message in `./result.csv`. - -
- -# Citation - -If you are interested in our work, please cite: - -```bibtex -@article{https://doi.org/10.1111/ssqu.13242, - author = {Rej\'{o}n Pi\tilde{n}a, Ren\'{e} Alejandro and Ma, Chenglong}, - title = {Classification Algorithm for Skin Color (CASCo): A new tool to measure skin color in social science research}, - journal = {Social Science Quarterly}, - volume = {n/a}, - number = {n/a}, - pages = {}, - keywords = {colorism, measurement, photo elicitation, racism, skin color, spectrometers}, - doi = {https://doi.org/10.1111/ssqu.13242}, - url = {https://onlinelibrary.wiley.com/doi/abs/10.1111/ssqu.13242}, - eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1111/ssqu.13242}, - abstract = {Abstract Objective A growing body of literature reveals that skin color has significant effects on people's income, health, education, and employment. However, the ways in which skin color has been measured in empirical research have been criticized for being inaccurate, if not subjective and biased. Objective Introduce an objective, automatic, accessible and customizable Classification Algorithm for Skin Color (CASCo). Methods We review the methods traditionally used to measure skin color (verbal scales, visual aids or color palettes, photo elicitation, spectrometers and image-based algorithms), noting their shortcomings. We highlight the need for a different tool to measure skin color Results We present CASCo, a (social researcher-friendly) Python library that uses face detection, skin segmentation and k-means clustering algorithms to determine the skin tone category of portraits. Conclusion After assessing the merits and shortcomings of all the methods available, we argue CASCo is well equipped to overcome most challenges and objections posed against its alternatives. While acknowledging its limitations, we contend that CASCo should complement researchers. toolkit in this area.} -} -``` - # Installation ## Install from pip @@ -214,9 +75,14 @@ pip install -e . --verbose # HOW TO USE > [!TIP] -> -> You can combine the following documents and [running examples](https://colab.research.google.com/drive/1k-cryEZ9PInJRXWIi17ib66ufYV2Ikwe?usp=sharing) in Google Colab to understand the usage of this library more intuitively. -> See the running examples [here](https://colab.research.google.com/drive/1k-cryEZ9PInJRXWIi17ib66ufYV2Ikwe?usp=sharing). +> +> You can combine the following documents +> and [running examples](https://colab.research.google.com/drive/1k-cryEZ9PInJRXWIi17ib66ufYV2Ikwe?usp=sharing) in +> Google +> Colab to understand the usage of this library more intuitively. +> +> See the running +> examples [here](https://colab.research.google.com/drive/1k-cryEZ9PInJRXWIi17ib66ufYV2Ikwe?usp=sharing). ## Quick Start @@ -321,12 +187,12 @@ options: ### Use Cases -#### 1. To process multiple images +#### 1. Process multiple images 1.1 Multiple filenames ```shell -stone -i (or --images) a.jpg b.png +stone -i (or --images) a.jpg b.png https://example.com/images/pic.jpg ``` 1.2 Images in some folder(s) @@ -339,25 +205,84 @@ NB: Supported image formats: `.jpg, .gif, .png, .jpeg, .webp, .tif`. In default (i.e., `stone` without `-i` option), the app will search images in current folder. -#### 2. To specify color categories +#### 2. Specify color categories -2.1 Use hex values +2.1 Use HEX values ```shell -stone -p (or --palette) #373028 #422811 #fbf2f3 +stone -p (or --palette) #373028 #422811 #513B2E ``` -NB: Values start with '#' and are separated by space. +NB: Values start with **'#'** and are separated by **space**. 2.2 Use RGB tuple values ```shell -stone -c 55,48,40 66,40,17 251,242,243 +stone -p 55,48,40 66,40,17 251,242,243 +``` + +NB: Values split by **comma ','**, multiple values are still separated by **space**. + +#### 3. Specify category labels + +You can assign the labels for the skin tone categories, for example: + +```text +"CA": "#373028", +"CB": "#422811", +"CC": "#513B2E", +... ``` -NB: Values split by comma ',', multiple values are still separated by space. +To achieve this, you can use the `-l` (or `--labels`) option: -#### 3. Specify output folder +3.1 Specify the labels directly using _spaces_ as delimiters, e.g., + +```shell +stone -l A B C D E F G H +``` + +3.2 Specify the range of labels based on this pattern: ``. + +Specifically, + +* ``: the **start** label, can be a letter (e.g., `A`) or a number (e.g., `1`); +* ``: the **end** label, can be a letter (e.g., `H`) or a number (e.g., `8`); +* ``: the **step** to generate the label sequence, can be a number (e.g., `2` or `-1`), **defaults to `1`**. +* ``: the **separator** between `` and ``, can be one of these symbols: `-`, `,`, `~`, `:`, `;`, `_`. + +Examples: + +```shell +stone -l A-H-1 +``` + +which is equivalent to `stone -l A-H` and `stone -l A B C D E F G H`. + +```shell +stone -l A-H-2 +``` + +which is equivalent to `stone -l A C E G`. + +```shell +stone -l 1-8 +``` + +which is equivalent to `stone -l 1 2 3 4 5 6 7 8`. + +```shell +stone -l 1-8-3 +``` + +which is equivalent to `stone -l 1 4 7`. + + +> [!IMPORTANT] +> +> Please make sure the number of labels is equal to the number of colors in the palette. + +#### 4. Specify output folder The app puts the final report (`result.csv`) in current folder in default. @@ -372,7 +297,7 @@ The output folder will be created if it does not exist. In `result.csv`, each row is showing the color information of each detected face. If more than one faces are detected, there will be multiple rows for that image. -#### 4. Store report images for debugging +#### 5. Store report images for debugging ```shell stone -d (or --debug) @@ -383,25 +308,25 @@ This option will store the report image (like the demo portrait above) in where `` indicates if the image is `color` or `bw` (black/white); `` is the number of faces detected in the image. -**By default, to save space, the app does not store report images.** +**By default, to save storage space, the app does not store report images.** Like in the `result.csv` file, there will be more than one report images if 2 or more faces were detected. -#### 5. Specify the types of the input image(s) +#### 6. Specify the types of the input image(s) -5.1 The input are color images +6.1 The input are color images ```shell stone -t (or --image_type) color ``` -5.2 The input are black/white images +6.2 The input are black/white images ```shell stone -t (or --image_type) bw ``` -5.3 **In default**, the app will detect the image type automatically, i.e., +6.3 **In default**, the app will detect the image type automatically, i.e., ```shell stone -t (or --image_type) auto @@ -456,7 +381,9 @@ For `bw` images, we use the `bw` palette to detect faces: **Leigh, A., & Susilo, T. (2009). Is voting skin-deep? Estimating the effect of candidate ballot photographs on election outcomes. _Journal of Economic Psychology_, 30(1), 61-70.** for more details.) -#### 6. Convert the `color` images to `black/white` images and then do the classification using `bw` palette +#### 7. Convert the `color` images to `black/white` images + +and then do the classification using `bw` palette ```shell stone -bw (or --black_white) @@ -483,12 +410,12 @@ NB: we did not do the opposite, i.e., convert `black/white` images to `color` im because the current AI models cannot accurately "guess" the color of the skin from a `black/white` image. It can further bias the analysis results. -#### 7. Tune parameters of face detection +#### 8. Tune parameters of face detection The rest parameters of `CONFIG` are used to detect face. Please refer to https://stackoverflow.com/a/20805153/8860079 for detailed information. -#### 8. Multiprocessing settings +#### 9. Multiprocessing settings ```shell stone --n_workers @@ -497,7 +424,7 @@ stone --n_workers Use `--n_workers` to specify the number of workers to process images in parallel, defaults to the number of CPUs in your system. -#### 9. Used as a library by importing into other projects +#### 10. Used as a library by importing into other projects You can refer to the following code snippet: @@ -553,6 +480,180 @@ The `result_json` will be like: } ``` +# Changelogs + +## v1.1.3 + +
+ Click here to show more. + +In this version, we have made the following changes: + +1. ✨ **NEW!**: We add new **patterns** in the `-l` (or `--labels`) option to set the skin tone labels. + * Now, you can use the following patterns to set the skin tone labels: + * **Default value**: the uppercase alphabet list leading by the image type (`C` for `color`; `B` + for `Black&White`). + * Specify the labels directly using _a space_ as delimiters, e.g., `-l A B C D E` or `-l 1 2 3 4 5`. + * Specify the range of labels using _a hyphen_ as delimiters, e.g., + * `-l A-E` (equivalent to `-l A B C D E`); + * `-l A-E-2` (equivalent to `-l A C E`); + * `-l 1-5` (equivalent to `-l 1 2 3 4 5`); + * `-l 1-10-3` (equivalent to `-l 1 4 7 10`); + * **NB**: The number of skin tone labels should be equal to the number of colors in the palette. + +
+ +## v1.1.2 + +
+ Click here to show more. + +In this version, we have made the following changes: + +1. 🐛 **FIX!**: We fixed a bug where the app will crash when using the `-bw` option. + Error message: `cannot reshape array of size 62500 into shape (3)`. +2. 🐛 **FIX!**: We fixed a bug where the app may identify the image type as `color` when using the `-bw` option. + +
+ +## v1.1.1 + +
+ Click here to show more. + +In this version, we have made the following changes: + +1. ✨ **NEW!**: We add the `-v` (or `--version`) option to show the version number. +2. ✨ **NEW!**: We add the `-r` (or `--recursive`) option to **enable** recursive search for images. + * For example, `stone -i ./path/to/images/ -r` will search all images in the `./path/to/images/` directory **and its + subdirectories**. + * `stone -i ./path/to/images/` will only search images in the `./path/to/images/` directory. +3. 🐛 **FIX!**: We fixed a bug where the app cannot correctly identify the current folder if `-i` option is not + specified. + +
+ +## v1.1.0 + +
+ Click here to show more. + +In this version, we have made the following changes: + +1. ✨ **NEW!**: Now, `stone` can not only be run on **the command line**, but can also be **imported** into other + projects for use. Check [this](#9-used-as-a-library-by-importing-into-other-projects) for more details. + * We expose the `process` and `show` functions in the `stone` package. +2. ✨ **NEW!**: We add `URL` support for the input images. + * Now, you can specify the input image as a URL, e.g., `https://example.com/images/pic.jpg`. Of course, you can mix + the URLs and local filenames. +3. ✨ **NEW!**: We add **recursive search** support for the input images. + * Now, when you specify the input image as a directory, e.g., `./path/to/images/`. + The app will search all images in the directory recursively. +4. 🧬 **CHANGE!**: We change the column header in `result.csv`: + * `prop` => `percent` + * `PERLA` => `tone label` +5. 🐛 **FIX!**: We fixed a bug where the app would not correctly sort files that did not contain numbers in their + filenames. + +
+ +## v1.0.1 + +
+ Click here to show more. + +1. 👋 **BYE**: We have removed the function to pop up a resulting window when processing a **single** image. + + * It can raise an error when running the app in a **web browser** environment, e.g., Jupyter Notebook or Google + Colab. + * If you want to see the processed image, please use the `-d` option to store the report image in the `./debug` + folder. + +
+ +## v1.0.0 + +
+ Click here to show more. + +🎉**We have officially released the 1.0.0 version of the library!** In this version, we have made the following changes: + +1. ✨ **NEW!**: We add the `threshold` parameter to control the minimum percentage of required face areas (Defaults to + 0.15). + * In previous versions, the library could incorrectly identify non-face areas as faces, such as shirts, collars, + necks, etc. + In order to improve its accuracy, the new version will further calculate the proportion of skin in the recognized + area + after recognizing the facial area. If it is less than the `threshold` value, the recognition area will be ignored. + (While it's still not perfect, it's an improvement over what it was before.) +2. ✨ **NEW!**: Now, we will back up the previous results if it already exists. + The backup file will be named as `result_bak_.csv`. +3. 🐛 **FIX!**: We fix the bug that the `image_type` option does not work in the previous version. +4. 🐛 **FIX!**: We fix the bug that the library will create an empty `log` folder when checking the help information by + running `stone -h`. + +
+ +## v0.2.0 + +
+ Click here to show more. + +In this version, we have made the following changes: + +1. ✨ **NEW!**: Now we support skin tone classification for **black and white** images. + * In this case, the app will use different skin tone palettes for color images and black/white images. + * We use a new parameter `-t` or `--image_type` to specify the type of the input image. + It can be `color`, `bw` or `auto`(default). + `auto` will let the app automatically detect whether the input is color or black/white image. + * We use a new parameter `-bw` or `--black_white` to specify whether to convert the input to black/white image. + If so, the app will convert the input to black/white image and then classify the skin tones based on the + black/white palette. + + For example: +
+ Processing color image + Processing black/white image +
+ +2. ✨ **NEW!**: Now we support **multiprocessing** for processing the images. It will largely speed up the processing. + * The number of processes is set to the number of CPU cores by default. + * You can specify the number of processes by `--n_workers` parameter. +3. 🧬 **CHANGE!**: We add more details in the report image to facilitate the debugging, as shown above. + * We add the face id in the report image. + * We add the effective face or skin area in the report image. In this case, the other areas are blurred. +4. 🧬 **CHANGE!**: Now, we save the report images into different folders based on their `image_type` (color or + black/white) and the number of detected faces. + * For example, if the input image is **color** and there are **2 faces** detected, the report image will be saved + in `./debug/color/faces_2/` folder. + * If the input image is **black/white** and no face has been detected, the report image will be saved + in `./debug/bw/faces_0/` folder. + * You can easily to tune the parameters and rerun the app based on the report images in the corresponding folder. +5. 🐛 **FIX!**: We fix the bug that the app will crash when the input image has dimensionality errors. + * Now, the app won't crash and will report the error message in `./result.csv`. + +
+ +# Citation + +If you are interested in our work, please cite: + +```bibtex +@article{https://doi.org/10.1111/ssqu.13242, + author = {Rej\'{o}n Pi\tilde{n}a, Ren\'{e} Alejandro and Ma, Chenglong}, + title = {Classification Algorithm for Skin Color (CASCo): A new tool to measure skin color in social science research}, + journal = {Social Science Quarterly}, + volume = {n/a}, + number = {n/a}, + pages = {}, + keywords = {colorism, measurement, photo elicitation, racism, skin color, spectrometers}, + doi = {https://doi.org/10.1111/ssqu.13242}, + url = {https://onlinelibrary.wiley.com/doi/abs/10.1111/ssqu.13242}, + eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1111/ssqu.13242}, + abstract = {Abstract Objective A growing body of literature reveals that skin color has significant effects on people's income, health, education, and employment. However, the ways in which skin color has been measured in empirical research have been criticized for being inaccurate, if not subjective and biased. Objective Introduce an objective, automatic, accessible and customizable Classification Algorithm for Skin Color (CASCo). Methods We review the methods traditionally used to measure skin color (verbal scales, visual aids or color palettes, photo elicitation, spectrometers and image-based algorithms), noting their shortcomings. We highlight the need for a different tool to measure skin color Results We present CASCo, a (social researcher-friendly) Python library that uses face detection, skin segmentation and k-means clustering algorithms to determine the skin tone category of portraits. Conclusion After assessing the merits and shortcomings of all the methods available, we argue CASCo is well equipped to overcome most challenges and objections posed against its alternatives. While acknowledging its limitations, we contend that CASCo should complement researchers. toolkit in this area.} +} +``` + # Contributing 👋 Welcome to **SkinToneClassifier**! We're excited to have your contributions. Here's how you can get involved: @@ -579,7 +680,9 @@ The `result_json` will be like: # Disclaimer -The images used in this project are from [Flickr-Faces-HQ Dataset (FFHQ)](https://github.com/NVlabs/ffhq-dataset), which is licensed under the [Creative Commons BY-NC-SA 4.0 license](https://github.com/NVlabs/ffhq-dataset/blob/master/LICENSE.txt) +The images used in this project are from [Flickr-Faces-HQ Dataset (FFHQ)](https://github.com/NVlabs/ffhq-dataset), which +is licensed under +the [Creative Commons BY-NC-SA 4.0 license](https://github.com/NVlabs/ffhq-dataset/blob/master/LICENSE.txt) Thank you for considering contributing to **SkinToneClassifier**. We value your input and look forward to collaborating with you! diff --git a/src/stone/package.py b/src/stone/package.py index ab57259..2e394bc 100644 --- a/src/stone/package.py +++ b/src/stone/package.py @@ -1,2 +1,2 @@ -__version__ = "1.2.0" +__version__ = "1.1.3" __package_name__ = "skin-tone-classifier"