├── FaceOff
├── __init__.py
└── AFR.py
├── .gitignore
├── examples
├── procedure.png
├── faces
│ ├── input
│ │ ├── john.jpg
│ │ ├── heath.jpg
│ │ ├── meryl.jpg
│ │ ├── ronald.jpg
│ │ └── winona.jpg
│ ├── target
│ │ ├── chris.jpg
│ │ ├── emma.jpg
│ │ ├── halle.jpg
│ │ ├── keanu.jpg
│ │ └── nick.jpg
│ ├── delta-example.png
│ ├── input-face-example.png
│ ├── target-face-example.png
│ └── combined-face-example.png
└── example.py
├── rlencevicius_poster.pdf
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
/FaceOff/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | results/
2 | __pycache__
3 | .vscode/
--------------------------------------------------------------------------------
/examples/procedure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/procedure.png
--------------------------------------------------------------------------------
/rlencevicius_poster.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/rlencevicius_poster.pdf
--------------------------------------------------------------------------------
/examples/faces/input/john.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/input/john.jpg
--------------------------------------------------------------------------------
/examples/faces/input/heath.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/input/heath.jpg
--------------------------------------------------------------------------------
/examples/faces/input/meryl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/input/meryl.jpg
--------------------------------------------------------------------------------
/examples/faces/input/ronald.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/input/ronald.jpg
--------------------------------------------------------------------------------
/examples/faces/input/winona.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/input/winona.jpg
--------------------------------------------------------------------------------
/examples/faces/target/chris.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/target/chris.jpg
--------------------------------------------------------------------------------
/examples/faces/target/emma.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/target/emma.jpg
--------------------------------------------------------------------------------
/examples/faces/target/halle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/target/halle.jpg
--------------------------------------------------------------------------------
/examples/faces/target/keanu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/target/keanu.jpg
--------------------------------------------------------------------------------
/examples/faces/target/nick.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/target/nick.jpg
--------------------------------------------------------------------------------
/examples/faces/delta-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/delta-example.png
--------------------------------------------------------------------------------
/examples/faces/input-face-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/input-face-example.png
--------------------------------------------------------------------------------
/examples/faces/target-face-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/target-face-example.png
--------------------------------------------------------------------------------
/examples/faces/combined-face-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/392781/FaceOff/HEAD/examples/faces/combined-face-example.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | torch>=1.13.1
2 | torchvision==0.8.2
3 | facenet-pytorch==2.5.1
4 | face_recognition
5 | face_recognition_models
6 | cmake
7 | dlib
8 | numpy
9 | scipy
10 | pyparsing==2.2.1
11 | Pillow
12 |
--------------------------------------------------------------------------------
/examples/example.py:
--------------------------------------------------------------------------------
1 | from FaceOff.AFR import load_data, Attack
2 | from PIL import Image
3 |
4 | # Load the data. This will detect and resize the faces
5 | inputs = load_data('./faces/input/')
6 | targets = load_data('./faces/target/')
7 |
8 | # Initialize the Attack object with
9 | adversarial = Attack(inputs[0], targets[3], optimizer='adam')
10 |
11 | # Perform adversarial training
12 | adversarial_tensor, mask_tensor, img = adversarial.train(detect=True, verbose=True)
13 |
14 | # Show the image with mask applied
15 | img.show()
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(
4 | name='FaceOff',
5 | version='0.0.0',
6 | description='Steps towards physical adversarial attacks on facial recognition',
7 | url='https://github.com/392781/FaceOff',
8 | author='Ronald Lencevičius',
9 | license='GNU General Public License v3 (GPLv3)',
10 | packages=['FaceOff'],
11 | install_requires=['torch>=1.13.1',
12 | 'torchvision==0.8.2',
13 | 'facenet-pytorch==2.5.1',
14 | 'face_recognition',
15 | 'face_recognition_models',
16 | 'cmake',
17 | 'dlib',
18 | 'numpy',
19 | 'Pillow'
20 | ],
21 |
22 | classifiers=[
23 | 'Intended Audience :: Science/Research',
24 | 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
25 | 'Operating System :: POSIX :: Linux',
26 | 'Programming Language :: Python :: 3',
27 | 'Programming Language :: Python :: 3.8',
28 | 'Topic :: Scientific/Engineering :: Artificial Intelligence',
29 | 'Topic :: Scientific/Engineering :: Image Recognition',
30 | ],
31 | )
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FaceOff
2 | ### Steps towards physical adversarial attacks on facial recognition
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Input image on the left is detected as the target image on the right after the mask has been applied.
12 |
13 | [![CC BY-SA 4.0][cc-by-sa-shield]][cc-by-sa]
14 |
15 | This work is licensed under a
16 | [Creative Commons Attribution-ShareAlike 4.0 International License][cc-by-sa].
17 |
18 | [![CC BY-SA 4.0][cc-by-sa-image]][cc-by-sa]
19 |
20 | [cc-by-sa]: http://creativecommons.org/licenses/by-sa/4.0/
21 | [cc-by-sa-image]: https://licensebuttons.net/l/by-sa/4.0/88x31.png
22 | [cc-by-sa-shield]: https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg
23 |
24 | ## Table of contents
25 |
26 | * [Table of contents](#table-of-contents)
27 | * [Description](#description)
28 | * [Installation](#installation)
29 | + [Requirements](#requirements)
30 | + [Instructions](#instructions)
31 | * [Citation](#citation)
32 | * [References](#references)
33 |
34 | ## Description
35 | The purpose of this library is to create adversarial attacks against the FaceNet face recognizer. This is the preliminary work towards creating a more robust physical attack using a mask that a person could wear over their face.
36 |
37 | For more details, please check out my [research poster](https://github.com/392781/FaceOff/blob/master/rlencevicius_poster.pdf).
38 |
39 | The current pipeline consists of an aligned input image with a calculated mask. This is then fed into a face detector using dlib's histogram of oriented gradients detector to test whether the face is still detected. This is then passed to FaceNet where which ouputs a face embedding and a loss which is then calculated and propagated back. This perturbs the input mask which generates enough of a disturbance to affect the loss.
40 |
41 | The loss function maximizes the Euclidean distance between the inputs' true identity and minimizes the distance between the adversarial input and the target image.
42 |
43 | An image of this process can be seen below.
44 |
45 |
46 |
47 |
48 |
49 |
50 | ## Installation
51 |
52 | ### Requirements
53 |
54 | This project works on Linux (Ubuntu 20.04). Windows and Mac are not supported but may work.
55 |
56 | ### Instructions
57 |
58 | 1. Create a virtual environment
59 |
60 | ```bash
61 | conda create -n facial_recognition python=3.8.5
62 | conda activate facial_recognition
63 | ```
64 |
65 | 2. Clone the repo
66 |
67 | ```git
68 | git clone https://github.com/392781/FaceOff.git
69 | ```
70 |
71 | 3. Install the required libraries
72 |
73 | ```bash
74 | pip install -r requirements.txt
75 | ```
76 |
77 | 4. Install FaceOff from inside the folder where `setup.py` is located
78 |
79 | ```bash
80 | pip install -e .
81 | ```
82 |
83 | 5. Import and use!
84 |
85 | ```python
86 | from FaceOff.AFR import load_data, Attack
87 | ```
88 |
89 | For training instructions look at [`example.py`](https://github.com/392781/FaceOff/blob/master/examples/example.py) to get started in less than 30 lines.
90 |
91 | ## Citation
92 | Please cite `FaceOff` if used in your research:
93 |
94 | ```tex
95 | @misc{FaceOff,
96 | author = {Ronaldas Paulius Lencevicius},
97 | howpublished = {GitHub},
98 | title = {Face-Off: Steps towards physical adversarial attacks on facial recognition},
99 | URL = {https://github.com/392781/FaceOff},
100 | month = {Aug}
101 | year = {2019},
102 | }
103 | ```
104 |
105 | ## References
106 | * Sharif, Mahmood, et al. "Accessorize to a crime: Real and stealthy attacks on state-of-the-art face recognition." Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security. ACM, 2016.
107 | * Wang, Mei, and Weihong Deng. "Deep face recognition: A survey." arXiv preprint arXiv:1804.06655 (2018).
108 | * MacDonald, Bruce. “Fooling Facial Detection with Fashion.” Towards Data Science, Towards Data Science, 4 June 2019, towardsdatascience.com/fooling-facial-detection-with-fashion-d668ed919eb.
109 | * Thys, Simen, et al. "Fooling automated surveillance cameras: adversarial patches to attack person detection." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition Workshops. 2019.
110 |
111 | Used the [PyTorch FaceNet implementation](https://github.com/timesler/facenet-pytorch) by Tim Esler
112 |
--------------------------------------------------------------------------------
/FaceOff/AFR.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import dlib
4 | import face_recognition as fr
5 | import face_recognition_models as frm
6 | import numpy as np
7 | import torch as t
8 | from torchvision.transforms import Compose, Normalize, ToTensor, ToPILImage
9 | from facenet_pytorch import InceptionResnetV1
10 | from PIL import Image, ImageDraw, ImageChops
11 |
12 | device = t.device('cuda' if t.cuda.is_available() else 'cpu')
13 |
14 | class Attack(object):
15 | """
16 | Class used to create adversarial facial recognition attacks
17 | """
18 | def __init__(self,
19 | input_img,
20 | target_img,
21 | seed=None,
22 | optimizer='sgd',
23 | lr = 1e-1,
24 | pretrained='vggface2'
25 | ):
26 | """
27 | Initialization for Attack class. Attack contains the following:
28 | input_tensor
29 | input_emb
30 | target_emb
31 | mask_tensor
32 | ref (mask reference for _apply)
33 |
34 | Parameters
35 | ----------
36 | input_img : PIL.Image
37 | Image to train on.
38 |
39 | target_img : PIL.Image
40 | Image to target the adversarial attack against.
41 |
42 | seed : int, optional
43 | Sets custom seed for reproducability. Default is generated randomly.
44 |
45 | optimizer : str, optional
46 | Takes in either 'sgd', 'adam', or 'adamax'. Default is 'adam'.
47 |
48 | lr : float, optional
49 | Learning rate. Default is 1e-1 or 0.1.
50 |
51 | pretrained : str, optional
52 | Pretrained weights for FaceNet. Options are 'vggface2' or 'casia-webface'.
53 | Default is 'vggface2'.
54 | """
55 | # Value inits
56 | if (seed != None) : np.random.seed(seed)
57 | self.MEAN = t.tensor([0.485, 0.456, 0.406], device=device)
58 | self.STD = t.tensor([0.229, 0.224, 0.225], device=device)
59 | self.LOSS = t.tensor(0, device=device)
60 |
61 | # Function inits
62 | self.imageize = ToPILImage()
63 | self.tensorize = ToTensor()
64 | self.normalize = Normalize(mean=self.MEAN.cpu().numpy(), std=self.STD.cpu().numpy())
65 | self.resnet = InceptionResnetV1(pretrained=pretrained).eval().to(device)
66 |
67 | # Training inputs
68 | # Original image - normalized and with embedding created.
69 | self.input_tensor = self.normalize(self.tensorize(input_img).to(device))
70 | self.input_emb = self.resnet(
71 | t.stack([
72 | self.input_tensor
73 | ])
74 | )
75 | # Target image - normalized and with embedding created.
76 | self.target_emb = self.resnet(
77 | t.stack([
78 | self.normalize(
79 | self.tensorize(target_img).to(device)
80 | )
81 | ])
82 | )
83 | # Adversarial embedding init
84 | self.adversarial_emb = None
85 | # Face mask init
86 | self.mask_tensor = self._create_mask(input_img)
87 | # Reference tensor used to apply mask
88 | self.ref = self.mask_tensor
89 |
90 | # Optimizer init
91 | try:
92 | if (optimizer == 'sgd'):
93 | self.opt = t.optim.SGD([self.mask_tensor], lr = lr, momentum = 0.9, weight_decay = 0.0001)
94 | elif (optimizer == 'adam'):
95 | self.opt = t.optim.Adam([self.mask_tensor], lr = lr, weight_decay = 0.0001)
96 | elif (optimizer == 'adamax'):
97 | self.opt = t.optim.Adamax([self.mask_tensor], lr = lr, weight_decay = 0.0001)
98 | except:
99 | print("Optimizer not supported, reverting to ADAM")
100 | self.opt = t.optim.Adam([self.mask_tensor], lr = lr, weight_decay = 0.0001)
101 |
102 |
103 | def train(self,
104 | epochs = 30,
105 | detect=False,
106 | verbose=False
107 | ):
108 | """
109 | Adversarial training process for facial recognition.
110 |
111 | Parameters
112 | ----------
113 | epochs : int, optional
114 | Number of training epochs. Default is 30.
115 |
116 | detect : bool, optional
117 | Perform facial detection during training process and log result. Default is False.
118 |
119 | verbose : bool, optional
120 | Output full embedding distance information during training. Default is False.
121 |
122 | Returns
123 | -------
124 | list
125 | Adversarial tensor, mask tensor, adversarial image
126 | """
127 | for i in range(1, epochs + 1):
128 | # Create adversarial tensor by applying normalized MASK to normalized INPUT
129 | self.view(self.mask_tensor).show()
130 | adversarial_tensor = self._apply(
131 | self.input_tensor,
132 | self.normalize(self.mask_tensor),
133 | self.ref)
134 | # Create embedding
135 | self.adversarial_emb = self.resnet(t.stack([adversarial_tensor]))
136 |
137 | # Calculate two distances - from adv to input and adv to target
138 | distance_to_image = self._emb_distance(self.adversarial_emb, self.input_emb)
139 | distance_to_target = self._emb_distance(self.adversarial_emb, self.target_emb)
140 | # Calculate loss - maximize distance to image, minimize distance to target
141 | self.LOSS = (-distance_to_image + distance_to_target)
142 | # Adversarially backpropagate the information back to original adversarial_tensor
143 | self.LOSS.backward(retain_graph=True)
144 | # Update optimizer and zero out gradients
145 | self.opt.step()
146 | self.opt.zero_grad()
147 | # Allow the updated mask to have only values (0, 255) or normalized (0, 1)
148 | self.mask_tensor.data.clamp_(0, 1)
149 |
150 | # Various logging information
151 | training_information = [f'Epoch {i}: \n Loss = {self.LOSS.item():.7f}']
152 | if verbose:
153 | training_information.append(f'\n Dist. to Image = {distance_to_image:.7f}')
154 | training_information.append(f'\n Dist. to Target = {distance_to_target:.7f}')
155 | if detect:
156 | face_loc = fr.face_locations(np.array(self.imageize(self._reverse_norm(adversarial_tensor).detach())))
157 | detected = False if not face_loc else True
158 | training_information.append(f'\n Face detection = {detected}')
159 | print(''.join(training_information))
160 |
161 | # Return original adversarial tensor, the adversarial image, and the mask tensor
162 | adversarial_image = self.imageize(self._reverse_norm(adversarial_tensor).detach())
163 | return adversarial_tensor, self.mask_tensor, adversarial_image
164 |
165 |
166 | def view(self,
167 | norm_image_tensor,
168 | norm_mask_tensor=None
169 | ):
170 | """
171 | Preview a tensor as an image
172 |
173 | Parameters
174 | ----------
175 | norm_image_tensor : torch.Tensor
176 | Image to convert.
177 | norm_mask_tensor : torch.Tensor, optional
178 | Mask to apply to image. Default is None.
179 |
180 | Returns
181 | -------
182 | PIL.Image
183 | """
184 | if norm_mask_tensor is not None:
185 | combined_tensor = self._apply(norm_image_tensor, norm_mask_tensor, self.ref)
186 | return self.imageize(self._reverse_norm(combined_tensor).detach())
187 | else:
188 | return self.imageize(self._reverse_norm(norm_image_tensor).detach())
189 |
190 |
191 | def _apply(self,
192 | image_tensor,
193 | mask_tensor,
194 | reference_tensor
195 | ):
196 | """
197 | Apply a mask over an image.
198 |
199 | Parameters
200 | ----------
201 | image_tensor : torch.Tensor
202 | Canvas to be used to apply mask on.
203 |
204 | mask_tensor : torch.Tensor
205 | Mask to apply over the image.
206 |
207 | reference_tensor : torch.Tensor
208 | Used to reference mask boundaries
209 |
210 | Returns
211 | -------
212 | torch.Tensor
213 | """
214 | return t.where((reference_tensor == 0), image_tensor, mask_tensor).to(device)
215 |
216 |
217 | def _create_mask(self, face_image):
218 | """
219 | Helper function to create a facial mask to cover lower portion of the
220 | face. Uses 'face_recognizer' library's landmark detector to build a
221 | list of tuples containing (x, y) coordinates of the lower chin area as
222 | well as the middle of the nose tip.
223 |
224 | A polygon is then drawn using those tuples creating a "taco" shaped
225 | face mask. This is then processed for each channel with a value of
226 | 0 for white areas and a value of 1 for black areas (the taco area)
227 |
228 | This will later be used as a tensor that takes in these given values
229 |
230 |
231 | Parameters
232 | ----------
233 | face_image : PIL.Image
234 | image of a detected face
235 |
236 | Returns
237 | -------
238 | mask_tensor : torch.Tensor
239 | mask tensor
240 | """
241 | # New image mask
242 | mask = Image.new('RGB', face_image.size, color=(0,0,0))
243 | # Draw on mask
244 | d = ImageDraw.Draw(mask)
245 |
246 | # Detect face landmarks
247 | landmarks = fr.face_landmarks(np.array(face_image))
248 | # Gross list comprehension magic to add coordinates from image to create face mask
249 | area = [landmark
250 | for landmark in landmarks[0]['chin']
251 | if landmark[1] > max(landmarks[0]['nose_tip'])[1]]
252 | area.append(landmarks[0]['nose_bridge'][1])
253 |
254 | # Fill the new face mask area
255 | d.polygon(area, fill=(255,255,255))
256 | # Create a numpy array and set type as floating point (used in training)
257 | mask_array = np.array(mask)
258 | mask_array = mask_array.astype(np.float32)
259 |
260 | # Fill the mask in with the color grey
261 | # C
262 | for i in range(mask_array.shape[0]):
263 | # C
264 | for j in range(mask_array.shape[1]):
265 | # C
266 | for k in range(mask_array.shape[2]):
267 | # Combo BREAKER
268 | if mask_array[i][j][k] == 255.:
269 | mask_array[i][j][k] = 0.5
270 | else:
271 | mask_array[i][j][k] = 0
272 |
273 | # Create the mask tensor and initialize gradient
274 | mask_tensor = ToTensor()(mask_array).to(device)
275 | mask_tensor.requires_grad_(True)
276 |
277 | return mask_tensor
278 |
279 |
280 | def _emb_distance(self, tensor_1, tensor_2):
281 | """
282 | Helper function to calculate Euclidean distance between two tensors.
283 |
284 | Parameters
285 | ----------
286 | tensor_1, tensor_2 : torch.Tensor
287 | Tensors used for distance calculation
288 |
289 | Returns
290 | distance_tensor : torch.Tensor
291 | Tensor containing distance value
292 | -------
293 |
294 | """
295 | distance_tensor = (tensor_1 - tensor_2).norm()
296 | return distance_tensor
297 |
298 |
299 | def _reverse_norm(self, image_tensor):
300 | """
301 | Reverses normalization for a given image_tensor
302 |
303 | Parameters
304 | ----------
305 | image_tensor : torch.Tensor
306 |
307 | Returns
308 | -------
309 | torch.Tensor
310 | """
311 | return image_tensor * self.STD[:, None, None] + self.MEAN[:, None, None]
312 |
313 |
314 |
315 | def detect_face(image_loc):
316 | """
317 | Helper function to run the facial detection and alignment process using
318 | dlib. Detects a given face and aligns it using dlib's 5 point landmark
319 | detector.
320 |
321 | Parameters
322 | ----------
323 | image_loc : numpy.array
324 | image file location
325 |
326 | Returns
327 | -------
328 | face_image : PIL.Image
329 | Resized face image
330 | """
331 | detector = dlib.get_frontal_face_detector()
332 | shape_predictor = dlib.shape_predictor(frm.pose_predictor_model_location())
333 | image = dlib.load_rgb_image(image_loc)
334 | dets = detector(image, 1)
335 |
336 | faces = dlib.full_object_detections()
337 | for detection in dets:
338 | faces.append(shape_predictor(image, detection))
339 |
340 | face_image = Image.fromarray(dlib.get_face_chip(image, faces[0], size=300))
341 |
342 | return face_image
343 |
344 |
345 | def load_data(path_to_data):
346 | """
347 | Helper function for loading image data. Allows user to load the input, target,
348 | and test images. Mask creation and offsetting must be done manually.
349 |
350 | Parameters
351 | ----------
352 | path_to_data : str
353 | Path to the given data. Ex: './faces/input/'
354 |
355 | Returns
356 | -------
357 | list : [PIL.Image]
358 | List of resized face images
359 | """
360 | img_files = [f for f in os.listdir(path_to_data) if re.search(r'.*\.(jpe?g|png)', f)]
361 | img_files_locs = [os.path.join(path_to_data, f) for f in img_files]
362 |
363 | image_list = []
364 |
365 | for loc in img_files_locs:
366 | image_list.append(detect_face(loc))
367 |
368 | return image_list
369 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Attribution-ShareAlike 4.0 International
2 |
3 | =======================================================================
4 |
5 | Creative Commons Corporation ("Creative Commons") is not a law firm and
6 | does not provide legal services or legal advice. Distribution of
7 | Creative Commons public licenses does not create a lawyer-client or
8 | other relationship. Creative Commons makes its licenses and related
9 | information available on an "as-is" basis. Creative Commons gives no
10 | warranties regarding its licenses, any material licensed under their
11 | terms and conditions, or any related information. Creative Commons
12 | disclaims all liability for damages resulting from their use to the
13 | fullest extent possible.
14 |
15 | Using Creative Commons Public Licenses
16 |
17 | Creative Commons public licenses provide a standard set of terms and
18 | conditions that creators and other rights holders may use to share
19 | original works of authorship and other material subject to copyright
20 | and certain other rights specified in the public license below. The
21 | following considerations are for informational purposes only, are not
22 | exhaustive, and do not form part of our licenses.
23 |
24 | Considerations for licensors: Our public licenses are
25 | intended for use by those authorized to give the public
26 | permission to use material in ways otherwise restricted by
27 | copyright and certain other rights. Our licenses are
28 | irrevocable. Licensors should read and understand the terms
29 | and conditions of the license they choose before applying it.
30 | Licensors should also secure all rights necessary before
31 | applying our licenses so that the public can reuse the
32 | material as expected. Licensors should clearly mark any
33 | material not subject to the license. This includes other CC-
34 | licensed material, or material used under an exception or
35 | limitation to copyright. More considerations for licensors:
36 | wiki.creativecommons.org/Considerations_for_licensors
37 |
38 | Considerations for the public: By using one of our public
39 | licenses, a licensor grants the public permission to use the
40 | licensed material under specified terms and conditions. If
41 | the licensor's permission is not necessary for any reason--for
42 | example, because of any applicable exception or limitation to
43 | copyright--then that use is not regulated by the license. Our
44 | licenses grant only permissions under copyright and certain
45 | other rights that a licensor has authority to grant. Use of
46 | the licensed material may still be restricted for other
47 | reasons, including because others have copyright or other
48 | rights in the material. A licensor may make special requests,
49 | such as asking that all changes be marked or described.
50 | Although not required by our licenses, you are encouraged to
51 | respect those requests where reasonable. More considerations
52 | for the public:
53 | wiki.creativecommons.org/Considerations_for_licensees
54 |
55 | =======================================================================
56 |
57 | Creative Commons Attribution-ShareAlike 4.0 International Public
58 | License
59 |
60 | By exercising the Licensed Rights (defined below), You accept and agree
61 | to be bound by the terms and conditions of this Creative Commons
62 | Attribution-ShareAlike 4.0 International Public License ("Public
63 | License"). To the extent this Public License may be interpreted as a
64 | contract, You are granted the Licensed Rights in consideration of Your
65 | acceptance of these terms and conditions, and the Licensor grants You
66 | such rights in consideration of benefits the Licensor receives from
67 | making the Licensed Material available under these terms and
68 | conditions.
69 |
70 |
71 | Section 1 -- Definitions.
72 |
73 | a. Adapted Material means material subject to Copyright and Similar
74 | Rights that is derived from or based upon the Licensed Material
75 | and in which the Licensed Material is translated, altered,
76 | arranged, transformed, or otherwise modified in a manner requiring
77 | permission under the Copyright and Similar Rights held by the
78 | Licensor. For purposes of this Public License, where the Licensed
79 | Material is a musical work, performance, or sound recording,
80 | Adapted Material is always produced where the Licensed Material is
81 | synched in timed relation with a moving image.
82 |
83 | b. Adapter's License means the license You apply to Your Copyright
84 | and Similar Rights in Your contributions to Adapted Material in
85 | accordance with the terms and conditions of this Public License.
86 |
87 | c. BY-SA Compatible License means a license listed at
88 | creativecommons.org/compatiblelicenses, approved by Creative
89 | Commons as essentially the equivalent of this Public License.
90 |
91 | d. Copyright and Similar Rights means copyright and/or similar rights
92 | closely related to copyright including, without limitation,
93 | performance, broadcast, sound recording, and Sui Generis Database
94 | Rights, without regard to how the rights are labeled or
95 | categorized. For purposes of this Public License, the rights
96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar
97 | Rights.
98 |
99 | e. Effective Technological Measures means those measures that, in the
100 | absence of proper authority, may not be circumvented under laws
101 | fulfilling obligations under Article 11 of the WIPO Copyright
102 | Treaty adopted on December 20, 1996, and/or similar international
103 | agreements.
104 |
105 | f. Exceptions and Limitations means fair use, fair dealing, and/or
106 | any other exception or limitation to Copyright and Similar Rights
107 | that applies to Your use of the Licensed Material.
108 |
109 | g. License Elements means the license attributes listed in the name
110 | of a Creative Commons Public License. The License Elements of this
111 | Public License are Attribution and ShareAlike.
112 |
113 | h. Licensed Material means the artistic or literary work, database,
114 | or other material to which the Licensor applied this Public
115 | License.
116 |
117 | i. Licensed Rights means the rights granted to You subject to the
118 | terms and conditions of this Public License, which are limited to
119 | all Copyright and Similar Rights that apply to Your use of the
120 | Licensed Material and that the Licensor has authority to license.
121 |
122 | j. Licensor means the individual(s) or entity(ies) granting rights
123 | under this Public License.
124 |
125 | k. Share means to provide material to the public by any means or
126 | process that requires permission under the Licensed Rights, such
127 | as reproduction, public display, public performance, distribution,
128 | dissemination, communication, or importation, and to make material
129 | available to the public including in ways that members of the
130 | public may access the material from a place and at a time
131 | individually chosen by them.
132 |
133 | l. Sui Generis Database Rights means rights other than copyright
134 | resulting from Directive 96/9/EC of the European Parliament and of
135 | the Council of 11 March 1996 on the legal protection of databases,
136 | as amended and/or succeeded, as well as other essentially
137 | equivalent rights anywhere in the world.
138 |
139 | m. You means the individual or entity exercising the Licensed Rights
140 | under this Public License. Your has a corresponding meaning.
141 |
142 |
143 | Section 2 -- Scope.
144 |
145 | a. License grant.
146 |
147 | 1. Subject to the terms and conditions of this Public License,
148 | the Licensor hereby grants You a worldwide, royalty-free,
149 | non-sublicensable, non-exclusive, irrevocable license to
150 | exercise the Licensed Rights in the Licensed Material to:
151 |
152 | a. reproduce and Share the Licensed Material, in whole or
153 | in part; and
154 |
155 | b. produce, reproduce, and Share Adapted Material.
156 |
157 | 2. Exceptions and Limitations. For the avoidance of doubt, where
158 | Exceptions and Limitations apply to Your use, this Public
159 | License does not apply, and You do not need to comply with
160 | its terms and conditions.
161 |
162 | 3. Term. The term of this Public License is specified in Section
163 | 6(a).
164 |
165 | 4. Media and formats; technical modifications allowed. The
166 | Licensor authorizes You to exercise the Licensed Rights in
167 | all media and formats whether now known or hereafter created,
168 | and to make technical modifications necessary to do so. The
169 | Licensor waives and/or agrees not to assert any right or
170 | authority to forbid You from making technical modifications
171 | necessary to exercise the Licensed Rights, including
172 | technical modifications necessary to circumvent Effective
173 | Technological Measures. For purposes of this Public License,
174 | simply making modifications authorized by this Section 2(a)
175 | (4) never produces Adapted Material.
176 |
177 | 5. Downstream recipients.
178 |
179 | a. Offer from the Licensor -- Licensed Material. Every
180 | recipient of the Licensed Material automatically
181 | receives an offer from the Licensor to exercise the
182 | Licensed Rights under the terms and conditions of this
183 | Public License.
184 |
185 | b. Additional offer from the Licensor -- Adapted Material.
186 | Every recipient of Adapted Material from You
187 | automatically receives an offer from the Licensor to
188 | exercise the Licensed Rights in the Adapted Material
189 | under the conditions of the Adapter's License You apply.
190 |
191 | c. No downstream restrictions. You may not offer or impose
192 | any additional or different terms or conditions on, or
193 | apply any Effective Technological Measures to, the
194 | Licensed Material if doing so restricts exercise of the
195 | Licensed Rights by any recipient of the Licensed
196 | Material.
197 |
198 | 6. No endorsement. Nothing in this Public License constitutes or
199 | may be construed as permission to assert or imply that You
200 | are, or that Your use of the Licensed Material is, connected
201 | with, or sponsored, endorsed, or granted official status by,
202 | the Licensor or others designated to receive attribution as
203 | provided in Section 3(a)(1)(A)(i).
204 |
205 | b. Other rights.
206 |
207 | 1. Moral rights, such as the right of integrity, are not
208 | licensed under this Public License, nor are publicity,
209 | privacy, and/or other similar personality rights; however, to
210 | the extent possible, the Licensor waives and/or agrees not to
211 | assert any such rights held by the Licensor to the limited
212 | extent necessary to allow You to exercise the Licensed
213 | Rights, but not otherwise.
214 |
215 | 2. Patent and trademark rights are not licensed under this
216 | Public License.
217 |
218 | 3. To the extent possible, the Licensor waives any right to
219 | collect royalties from You for the exercise of the Licensed
220 | Rights, whether directly or through a collecting society
221 | under any voluntary or waivable statutory or compulsory
222 | licensing scheme. In all other cases the Licensor expressly
223 | reserves any right to collect such royalties.
224 |
225 |
226 | Section 3 -- License Conditions.
227 |
228 | Your exercise of the Licensed Rights is expressly made subject to the
229 | following conditions.
230 |
231 | a. Attribution.
232 |
233 | 1. If You Share the Licensed Material (including in modified
234 | form), You must:
235 |
236 | a. retain the following if it is supplied by the Licensor
237 | with the Licensed Material:
238 |
239 | i. identification of the creator(s) of the Licensed
240 | Material and any others designated to receive
241 | attribution, in any reasonable manner requested by
242 | the Licensor (including by pseudonym if
243 | designated);
244 |
245 | ii. a copyright notice;
246 |
247 | iii. a notice that refers to this Public License;
248 |
249 | iv. a notice that refers to the disclaimer of
250 | warranties;
251 |
252 | v. a URI or hyperlink to the Licensed Material to the
253 | extent reasonably practicable;
254 |
255 | b. indicate if You modified the Licensed Material and
256 | retain an indication of any previous modifications; and
257 |
258 | c. indicate the Licensed Material is licensed under this
259 | Public License, and include the text of, or the URI or
260 | hyperlink to, this Public License.
261 |
262 | 2. You may satisfy the conditions in Section 3(a)(1) in any
263 | reasonable manner based on the medium, means, and context in
264 | which You Share the Licensed Material. For example, it may be
265 | reasonable to satisfy the conditions by providing a URI or
266 | hyperlink to a resource that includes the required
267 | information.
268 |
269 | 3. If requested by the Licensor, You must remove any of the
270 | information required by Section 3(a)(1)(A) to the extent
271 | reasonably practicable.
272 |
273 | b. ShareAlike.
274 |
275 | In addition to the conditions in Section 3(a), if You Share
276 | Adapted Material You produce, the following conditions also apply.
277 |
278 | 1. The Adapter's License You apply must be a Creative Commons
279 | license with the same License Elements, this version or
280 | later, or a BY-SA Compatible License.
281 |
282 | 2. You must include the text of, or the URI or hyperlink to, the
283 | Adapter's License You apply. You may satisfy this condition
284 | in any reasonable manner based on the medium, means, and
285 | context in which You Share Adapted Material.
286 |
287 | 3. You may not offer or impose any additional or different terms
288 | or conditions on, or apply any Effective Technological
289 | Measures to, Adapted Material that restrict exercise of the
290 | rights granted under the Adapter's License You apply.
291 |
292 |
293 | Section 4 -- Sui Generis Database Rights.
294 |
295 | Where the Licensed Rights include Sui Generis Database Rights that
296 | apply to Your use of the Licensed Material:
297 |
298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right
299 | to extract, reuse, reproduce, and Share all or a substantial
300 | portion of the contents of the database;
301 |
302 | b. if You include all or a substantial portion of the database
303 | contents in a database in which You have Sui Generis Database
304 | Rights, then the database in which You have Sui Generis Database
305 | Rights (but not its individual contents) is Adapted Material,
306 | including for purposes of Section 3(b); and
307 |
308 | c. You must comply with the conditions in Section 3(a) if You Share
309 | all or a substantial portion of the contents of the database.
310 |
311 | For the avoidance of doubt, this Section 4 supplements and does not
312 | replace Your obligations under this Public License where the Licensed
313 | Rights include other Copyright and Similar Rights.
314 |
315 |
316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability.
317 |
318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
328 |
329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
338 |
339 | c. The disclaimer of warranties and limitation of liability provided
340 | above shall be interpreted in a manner that, to the extent
341 | possible, most closely approximates an absolute disclaimer and
342 | waiver of all liability.
343 |
344 |
345 | Section 6 -- Term and Termination.
346 |
347 | a. This Public License applies for the term of the Copyright and
348 | Similar Rights licensed here. However, if You fail to comply with
349 | this Public License, then Your rights under this Public License
350 | terminate automatically.
351 |
352 | b. Where Your right to use the Licensed Material has terminated under
353 | Section 6(a), it reinstates:
354 |
355 | 1. automatically as of the date the violation is cured, provided
356 | it is cured within 30 days of Your discovery of the
357 | violation; or
358 |
359 | 2. upon express reinstatement by the Licensor.
360 |
361 | For the avoidance of doubt, this Section 6(b) does not affect any
362 | right the Licensor may have to seek remedies for Your violations
363 | of this Public License.
364 |
365 | c. For the avoidance of doubt, the Licensor may also offer the
366 | Licensed Material under separate terms or conditions or stop
367 | distributing the Licensed Material at any time; however, doing so
368 | will not terminate this Public License.
369 |
370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
371 | License.
372 |
373 |
374 | Section 7 -- Other Terms and Conditions.
375 |
376 | a. The Licensor shall not be bound by any additional or different
377 | terms or conditions communicated by You unless expressly agreed.
378 |
379 | b. Any arrangements, understandings, or agreements regarding the
380 | Licensed Material not stated herein are separate from and
381 | independent of the terms and conditions of this Public License.
382 |
383 |
384 | Section 8 -- Interpretation.
385 |
386 | a. For the avoidance of doubt, this Public License does not, and
387 | shall not be interpreted to, reduce, limit, restrict, or impose
388 | conditions on any use of the Licensed Material that could lawfully
389 | be made without permission under this Public License.
390 |
391 | b. To the extent possible, if any provision of this Public License is
392 | deemed unenforceable, it shall be automatically reformed to the
393 | minimum extent necessary to make it enforceable. If the provision
394 | cannot be reformed, it shall be severed from this Public License
395 | without affecting the enforceability of the remaining terms and
396 | conditions.
397 |
398 | c. No term or condition of this Public License will be waived and no
399 | failure to comply consented to unless expressly agreed to by the
400 | Licensor.
401 |
402 | d. Nothing in this Public License constitutes or may be interpreted
403 | as a limitation upon, or waiver of, any privileges and immunities
404 | that apply to the Licensor or You, including from the legal
405 | processes of any jurisdiction or authority.
406 |
407 |
408 | =======================================================================
409 |
410 | Creative Commons is not a party to its public licenses.
411 | Notwithstanding, Creative Commons may elect to apply one of its public
412 | licenses to material it publishes and in those instances will be
413 | considered the “Licensor.” The text of the Creative Commons public
414 | licenses is dedicated to the public domain under the CC0 Public Domain
415 | Dedication. Except for the limited purpose of indicating that material
416 | is shared under a Creative Commons public license or as otherwise
417 | permitted by the Creative Commons policies published at
418 | creativecommons.org/policies, Creative Commons does not authorize the
419 | use of the trademark "Creative Commons" or any other trademark or logo
420 | of Creative Commons without its prior written consent including,
421 | without limitation, in connection with any unauthorized modifications
422 | to any of its public licenses or any other arrangements,
423 | understandings, or agreements concerning use of licensed material. For
424 | the avoidance of doubt, this paragraph does not form part of the public
425 | licenses.
426 |
427 | Creative Commons may be contacted at creativecommons.org.
428 |
--------------------------------------------------------------------------------