Create gh-pages branch via GitHub
This commit is contained in:
commit
edbbf79bc1
9 changed files with 778 additions and 0 deletions
BIN
images/bg_hr.png
Normal file
BIN
images/bg_hr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 943 B |
BIN
images/blacktocat.png
Normal file
BIN
images/blacktocat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
images/icon_download.png
Normal file
BIN
images/icon_download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
images/sprite_download.png
Normal file
BIN
images/sprite_download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
279
index.html
Normal file
279
index.html
Normal file
|
@ -0,0 +1,279 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8' />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
||||||
|
<meta name="description" content="Cat vs. dog drawings categorization : A university project" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css">
|
||||||
|
|
||||||
|
<title>Cat vs. dog drawings categorization</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- HEADER -->
|
||||||
|
<div id="header_wrap" class="outer">
|
||||||
|
<header class="inner">
|
||||||
|
<a id="forkme_banner" href="https://github.com/jeena/catdog">View on GitHub</a>
|
||||||
|
|
||||||
|
<h1 id="project_title">Cat vs. dog drawings categorization</h1>
|
||||||
|
<h2 id="project_tagline">A university project</h2>
|
||||||
|
|
||||||
|
<section id="downloads">
|
||||||
|
<a class="zip_download_link" href="https://github.com/jeena/catdog/zipball/master">Download this project as a .zip file</a>
|
||||||
|
<a class="tar_download_link" href="https://github.com/jeena/catdog/tarball/master">Download this project as a tar.gz file</a>
|
||||||
|
</section>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MAIN CONTENT -->
|
||||||
|
<div id="main_content_wrap" class="outer">
|
||||||
|
<section id="main_content" class="inner">
|
||||||
|
<h1>
|
||||||
|
<a name="1-introduction" class="anchor" href="#1-introduction"><span class="octicon octicon-link"></span></a>1. Introduction</h1>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="11-goal" class="anchor" href="#11-goal"><span class="octicon octicon-link"></span></a>1.1. Goal</h2>
|
||||||
|
|
||||||
|
<p>The goal of this project was to give a computer a drawing of either a cat's or a dog's face and let it recognize with high probability whether a cat or a dog is shown.</p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="12-scope" class="anchor" href="#12-scope"><span class="octicon octicon-link"></span></a>1.2. Scope</h2>
|
||||||
|
|
||||||
|
<p>First I thought that I would get lots of people to draw cat and dog faces for me, but I later realized that it was far too time consuming. Therefore I had to change the scope from recognizing random peoples drawings to recognizing my own drawings, which is obviously easier. Everything else did not change that much, I would just get better results.</p>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a name="2-preparation" class="anchor" href="#2-preparation"><span class="octicon octicon-link"></span></a>2. Preparation</h1>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="21-drawing-and-taking-a-photo" class="anchor" href="#21-drawing-and-taking-a-photo"><span class="octicon octicon-link"></span></a>2.1. Drawing and taking a photo</h2>
|
||||||
|
|
||||||
|
<p><img src="https://jeena.net/images/2013/catdog/drawing-taking-photo.jpg" alt="The raw drawings"></p>
|
||||||
|
|
||||||
|
<p>I drew eight A4 sheets of such cat and dog faces which resulted in 64 dog faces and 60 cat faces. Then I took pictures of them with my digital camera.</p>
|
||||||
|
|
||||||
|
<p>There was a huge difference in quality between the pictures I took with my iPhone 4 camera and the ones I took with my Nikon D5000. In fact I was not able to use the pictures I took with the iPhone because it was impossible to find straight lines in them.</p>
|
||||||
|
|
||||||
|
<p>You can see the result here, one with the iPhone image as a source and the other with the Nikon image:</p>
|
||||||
|
|
||||||
|
<p><img src="https://jeena.net/images/2013/catdog/iphone-sample.jpg" alt="iPhone vs. Nikon sample"></p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="22-photoshop" class="anchor" href="#22-photoshop"><span class="octicon octicon-link"></span></a>2.2. Photoshop</h2>
|
||||||
|
|
||||||
|
<p>I cleaned up the drawings so it would be easier for the algorithm to find everything. I opened the pictures of the drawings in Photoshop and played with the contrast and brightness settings.</p>
|
||||||
|
|
||||||
|
<p>Then I cut out all the drawings from the big image and saved them as a black and white PNG images without dither.</p>
|
||||||
|
|
||||||
|
<p><img src="https://jeena.net/images/2013/catdog/photoshop.jpg" alt="Steps in Photoshop"></p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="23-resizing" class="anchor" href="#23-resizing"><span class="octicon octicon-link"></span></a>2.3. Resizing</h2>
|
||||||
|
|
||||||
|
<p>I wrote a small shellscript which would take all pictures and resize them proportionally to a max width and height of 200 px. It also fills up the missing borders with a white background color. To do that I used the <a href="www.imagemagick.org">ImageMagick</a> software suite:</p>
|
||||||
|
|
||||||
|
<pre>#!/bin/sh
|
||||||
|
|
||||||
|
NEW="new_$1"
|
||||||
|
rm -rf $NEW
|
||||||
|
mkdir $NEW
|
||||||
|
|
||||||
|
for i in `ls -1 $1`
|
||||||
|
do
|
||||||
|
convert $1/$i \
|
||||||
|
-adaptive-resize 200x200\> \
|
||||||
|
-size 200x200 xc:white +swap \
|
||||||
|
-gravity center \
|
||||||
|
-composite \
|
||||||
|
$NEW/$i
|
||||||
|
done</pre>
|
||||||
|
|
||||||
|
<p>After that all the images had uniform sizes and colors so that I was able to compare them in a meaningful way.</p>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a name="3-feature-extraction" class="anchor" href="#3-feature-extraction"><span class="octicon octicon-link"></span></a>3. Feature extraction</h1>
|
||||||
|
|
||||||
|
<p>The next step was to extract the features from the images. In other words find things in the pictures that would be unique enough to make a difference between cats and dogs but broad enough so that all dogs would fall into one category and all cats into the other.</p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="31-straight-lines" class="anchor" href="#31-straight-lines"><span class="octicon octicon-link"></span></a>3.1. Straight lines</h2>
|
||||||
|
|
||||||
|
<p>The first thing which came to mind was counting and doing other stuff with straight lines in the image.</p>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
<a name="311-canny-edge-detector" class="anchor" href="#311-canny-edge-detector"><span class="octicon octicon-link"></span></a>3.1.1 Canny edge detector</h3>
|
||||||
|
|
||||||
|
<p>I used an edge detector algorithm called Canny to preprocess the images which - as the name implies - finds edges in images. Because of my preparation with Photoshop it was quite easy for it to find them. It is not easy to see this step with my drawings, so here is a picture of how it looks like when you do this with a photo instead:</p>
|
||||||
|
|
||||||
|
<p><img src="https://jeena.net/images/2013/catdog/canny.jpg" alt="Canny on a photo from Wikipedia"></p>
|
||||||
|
|
||||||
|
<p>It basically removes noise with a gausian filter and then finds the intentisty gradians of the image with help of some trigonometry.</p>
|
||||||
|
|
||||||
|
<p>I did not implement the algorithm myself, instead I used the often used <a href="http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html">OpenCV implementation</a>.</p>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
<a name="312-hough-transform" class="anchor" href="#312-hough-transform"><span class="octicon octicon-link"></span></a>3.1.2 Hough transform</h3>
|
||||||
|
|
||||||
|
<p>To find the lines I used the <a href="https://en.wikipedia.org/wiki/Hough_transform">Hough transform</a> algorithm. The red lines are those which the Hough transform algorithm found in the example picture:</p>
|
||||||
|
|
||||||
|
<p><img src="https://jeena.net/images/2013/catdog/hough.png" alt="Hough lines"></p>
|
||||||
|
|
||||||
|
<p>It essentially groups edges, which can be imperfect, to object candidates by performing an explicit voting procedure. Detecting straight lines can be done by describing them as <code>y = mx + b</code> where <code>m</code> is the slope of the line and <code>b</code> is the intercept. The line is not represented by descrete points <code>(x1,y1)(x2,y2)</code> but instead as a <code>point(x,y)</code> in the parameter space, which makes detection of lines, which are a bit off, possible. In practice it is still more complicated, please read the <a href="https://en.wikipedia.org/wiki/Hough_transform">Wikipedia article</a> about it.</p>
|
||||||
|
|
||||||
|
<p>I did not implement it myself but used the often used and tested probabilistic <a href="http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghlinesp#houghlinesp">OpenCV implementation</a>.</p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="32-line-features" class="anchor" href="#32-line-features"><span class="octicon octicon-link"></span></a>3.2. Line features</h2>
|
||||||
|
|
||||||
|
<p>I extracted these features from the lines:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>amount of lines</li>
|
||||||
|
<li>average length of lines</li>
|
||||||
|
<li>average angle of lines</li>
|
||||||
|
</ul><h2>
|
||||||
|
<a name="33-other-features" class="anchor" href="#33-other-features"><span class="octicon octicon-link"></span></a>3.3. Other features</h2>
|
||||||
|
|
||||||
|
<p>I also extracted the amount of black pixels in the image to use it as a possible feature which was not using the extracted lines.</p>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a name="4-k-nearest-neighbor-algorithm" class="anchor" href="#4-k-nearest-neighbor-algorithm"><span class="octicon octicon-link"></span></a>4. <em>k</em>-nearest neighbor algorithm</h1>
|
||||||
|
|
||||||
|
<p>I chose to use the <em>k</em>-Nearest Neighbors algorithm which only locally looks at the neighbors of the document in a radius predefined by the user. It assumes that the document is of the same category as the highest number of neighbors within this radius.
|
||||||
|
In the following figure you can see that depending if the user choses k = 3, as shown by the solid line, the algorithm will conclude that the document in the center (green smiley) is of the type triangle because most of this three neighbors are triangles. If on the other hand the user choses k = 7, as shown by the dotted line, then the amount of neighbors which are rectangles is greater as the amount of neighbors which are triangles, so it concludes that the smiley is of type rectangle.</p>
|
||||||
|
|
||||||
|
<p><img src="https://jeena.net/images/2013/catdog/k-nearest-neighbours.png" alt="k-Nearest Neighbours as a graphic"></p>
|
||||||
|
|
||||||
|
<p>In the picture above you see how it would look with two dimensions. I have been using four features so the algorithm had to check the distance to the neighbours in four dimensions. This is not really more difficult, it is just more to calculate.</p>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a name="5-results" class="anchor" href="#5-results"><span class="octicon octicon-link"></span></a>5. Results</h1>
|
||||||
|
|
||||||
|
<p>The results were quite encouraging, I assume it is because I only used one style to draw the dogs and one style to draw the cats.</p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="51-k-fold-cross-validation" class="anchor" href="#51-k-fold-cross-validation"><span class="octicon octicon-link"></span></a>5.1. k-fold Cross-validation</h2>
|
||||||
|
|
||||||
|
<p>I used 10 fold cross-validation for every test I did, which means that I used 90% of the available data for the learning algorithms and then the remaining 10% to test how they performed. I repeated this ten times until all data had been used for testing once.</p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="52-results-with-all-features" class="anchor" href="#52-results-with-all-features"><span class="octicon octicon-link"></span></a>5.2. Results with all features</h2>
|
||||||
|
|
||||||
|
<p>When I used all of the features and three nearest neighbours I got amazing 100% accuracy, which was kind of suspect because that normally means that you most probably did something wrong.</p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<a name="53-results-with-a-reduced-feature-set" class="anchor" href="#53-results-with-a-reduced-feature-set"><span class="octicon octicon-link"></span></a>5.3. Results with a reduced feature set</h2>
|
||||||
|
|
||||||
|
<p>Therefore I tried to reduce the features to check if it would perform worse.</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>When I removed the information about the amount of black pixels basically nothing happened.</li>
|
||||||
|
<li>When I removed the information about the amount of lines and average length at least I got a couple of wrong categorized images, the accuracy went down to 95%.</li>
|
||||||
|
<li>When I removed the information about the average angle of the lines, that was when I got significant errors. The accuracy dropped down to about 60%, which is still better then pure chance.</li>
|
||||||
|
</ol><p>So it seems like the best feature to detect cat and dog face drawings done by me was the average angle of the straight lines in the image.</p>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a name="6-future-study" class="anchor" href="#6-future-study"><span class="octicon octicon-link"></span></a>6. Future study</h1>
|
||||||
|
|
||||||
|
<p>The most important next step would be to gather many more drawings done by other people who use other styles to draw cat and dog faces.</p>
|
||||||
|
|
||||||
|
<p>Then it would be interesting to use other learning algorithms like Bayes, Perceptron, etc.</p>
|
||||||
|
|
||||||
|
<p>And then it would be interesting to use this approach on photos of real cats and dogs.</p>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a name="7-code" class="anchor" href="#7-code"><span class="octicon octicon-link"></span></a>7. Code</h1>
|
||||||
|
|
||||||
|
<pre><code>#!/usr/bin/env python
|
||||||
|
|
||||||
|
import cv2, cv, sys, math, os, numpy
|
||||||
|
from scipy.spatial import KDTree
|
||||||
|
|
||||||
|
def extractFeatures(label):
|
||||||
|
|
||||||
|
directory = "img/" + label + "/"
|
||||||
|
|
||||||
|
features = []
|
||||||
|
|
||||||
|
for fn in os.listdir(directory):
|
||||||
|
|
||||||
|
img = cv2.imread(directory + fn, 0)
|
||||||
|
|
||||||
|
# find edges
|
||||||
|
canny = cv2.Canny(img, 50, 100)
|
||||||
|
|
||||||
|
# find colored
|
||||||
|
black_pixels = numpy.count_nonzero(img)
|
||||||
|
|
||||||
|
# find lines lines
|
||||||
|
lines = cv2.HoughLinesP(canny, 1, math.pi/360, 5, None, 10, 1)
|
||||||
|
|
||||||
|
lengths = []
|
||||||
|
angles = []
|
||||||
|
try:
|
||||||
|
for line in lines[0]:
|
||||||
|
x1, y1, x2, y2 = line
|
||||||
|
|
||||||
|
# Pythagoras
|
||||||
|
a2 = math.pow((x1-x2), 2)
|
||||||
|
b2 = math.pow((y1-y2), 2)
|
||||||
|
length = int(math.sqrt(a2 + b2))
|
||||||
|
lengths.append(length)
|
||||||
|
|
||||||
|
angle = int(math.degrees(math.atan((y1-y2) / (x1-x2))))
|
||||||
|
angles.append(angle)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# print out everything
|
||||||
|
lines_count = len(lengths)
|
||||||
|
mid_length = sum(lengths) / lines_count
|
||||||
|
mid_angle = sum(angles) / lines_count
|
||||||
|
|
||||||
|
features.append([
|
||||||
|
[lines_count, mid_length, mid_angle, black_pixels],
|
||||||
|
label
|
||||||
|
])
|
||||||
|
|
||||||
|
return features
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
cats = extractFeatures("cat")
|
||||||
|
dogs = extractFeatures("dog")
|
||||||
|
|
||||||
|
test_count = 5
|
||||||
|
|
||||||
|
test_data = dogs[:test_count] + cats[:test_count]
|
||||||
|
test_labels = map(lambda a: a[1], test_data)
|
||||||
|
test_features = map(lambda a: a[0], test_data)
|
||||||
|
|
||||||
|
data = cats[test_count:] + dogs[test_count:]
|
||||||
|
labels = map(lambda a: a[1], data)
|
||||||
|
features = map(lambda a: a[0], data)
|
||||||
|
|
||||||
|
tree = KDTree(features)
|
||||||
|
|
||||||
|
for t in xrange(0, test_count * 2):
|
||||||
|
d, i = tree.query(test_features[t], k=3)
|
||||||
|
print "-"
|
||||||
|
for j in xrange(0, len(i)):
|
||||||
|
print test_labels[t] + " is a " + labels[i[j]]
|
||||||
|
</code></pre>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<div id="footer_wrap" class="outer">
|
||||||
|
<footer class="inner">
|
||||||
|
<p class="copyright">Cat vs. dog drawings categorization maintained by <a href="https://github.com/jeena">jeena</a></p>
|
||||||
|
<p>Published with <a href="http://pages.github.com">GitHub Pages</a></p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
1
javascripts/main.js
Normal file
1
javascripts/main.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log('This would be the main JS file.');
|
1
params.json
Normal file
1
params.json
Normal file
File diff suppressed because one or more lines are too long
70
stylesheets/pygment_trac.css
Normal file
70
stylesheets/pygment_trac.css
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
.highlight .hll { background-color: #ffffcc }
|
||||||
|
.highlight { background: #f0f3f3; }
|
||||||
|
.highlight .c { color: #0099FF; font-style: italic } /* Comment */
|
||||||
|
.highlight .err { color: #AA0000; background-color: #FFAAAA } /* Error */
|
||||||
|
.highlight .k { color: #006699; font-weight: bold } /* Keyword */
|
||||||
|
.highlight .o { color: #555555 } /* Operator */
|
||||||
|
.highlight .cm { color: #0099FF; font-style: italic } /* Comment.Multiline */
|
||||||
|
.highlight .cp { color: #009999 } /* Comment.Preproc */
|
||||||
|
.highlight .c1 { color: #0099FF; font-style: italic } /* Comment.Single */
|
||||||
|
.highlight .cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */
|
||||||
|
.highlight .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */
|
||||||
|
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||||
|
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
||||||
|
.highlight .gh { color: #003300; font-weight: bold } /* Generic.Heading */
|
||||||
|
.highlight .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */
|
||||||
|
.highlight .go { color: #AAAAAA } /* Generic.Output */
|
||||||
|
.highlight .gp { color: #000099; font-weight: bold } /* Generic.Prompt */
|
||||||
|
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||||
|
.highlight .gu { color: #003300; font-weight: bold } /* Generic.Subheading */
|
||||||
|
.highlight .gt { color: #99CC66 } /* Generic.Traceback */
|
||||||
|
.highlight .kc { color: #006699; font-weight: bold } /* Keyword.Constant */
|
||||||
|
.highlight .kd { color: #006699; font-weight: bold } /* Keyword.Declaration */
|
||||||
|
.highlight .kn { color: #006699; font-weight: bold } /* Keyword.Namespace */
|
||||||
|
.highlight .kp { color: #006699 } /* Keyword.Pseudo */
|
||||||
|
.highlight .kr { color: #006699; font-weight: bold } /* Keyword.Reserved */
|
||||||
|
.highlight .kt { color: #007788; font-weight: bold } /* Keyword.Type */
|
||||||
|
.highlight .m { color: #FF6600 } /* Literal.Number */
|
||||||
|
.highlight .s { color: #CC3300 } /* Literal.String */
|
||||||
|
.highlight .na { color: #330099 } /* Name.Attribute */
|
||||||
|
.highlight .nb { color: #336666 } /* Name.Builtin */
|
||||||
|
.highlight .nc { color: #00AA88; font-weight: bold } /* Name.Class */
|
||||||
|
.highlight .no { color: #336600 } /* Name.Constant */
|
||||||
|
.highlight .nd { color: #9999FF } /* Name.Decorator */
|
||||||
|
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||||
|
.highlight .ne { color: #CC0000; font-weight: bold } /* Name.Exception */
|
||||||
|
.highlight .nf { color: #CC00FF } /* Name.Function */
|
||||||
|
.highlight .nl { color: #9999FF } /* Name.Label */
|
||||||
|
.highlight .nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */
|
||||||
|
.highlight .nt { color: #330099; font-weight: bold } /* Name.Tag */
|
||||||
|
.highlight .nv { color: #003333 } /* Name.Variable */
|
||||||
|
.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */
|
||||||
|
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||||
|
.highlight .mf { color: #FF6600 } /* Literal.Number.Float */
|
||||||
|
.highlight .mh { color: #FF6600 } /* Literal.Number.Hex */
|
||||||
|
.highlight .mi { color: #FF6600 } /* Literal.Number.Integer */
|
||||||
|
.highlight .mo { color: #FF6600 } /* Literal.Number.Oct */
|
||||||
|
.highlight .sb { color: #CC3300 } /* Literal.String.Backtick */
|
||||||
|
.highlight .sc { color: #CC3300 } /* Literal.String.Char */
|
||||||
|
.highlight .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */
|
||||||
|
.highlight .s2 { color: #CC3300 } /* Literal.String.Double */
|
||||||
|
.highlight .se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */
|
||||||
|
.highlight .sh { color: #CC3300 } /* Literal.String.Heredoc */
|
||||||
|
.highlight .si { color: #AA0000 } /* Literal.String.Interpol */
|
||||||
|
.highlight .sx { color: #CC3300 } /* Literal.String.Other */
|
||||||
|
.highlight .sr { color: #33AAAA } /* Literal.String.Regex */
|
||||||
|
.highlight .s1 { color: #CC3300 } /* Literal.String.Single */
|
||||||
|
.highlight .ss { color: #FFCC33 } /* Literal.String.Symbol */
|
||||||
|
.highlight .bp { color: #336666 } /* Name.Builtin.Pseudo */
|
||||||
|
.highlight .vc { color: #003333 } /* Name.Variable.Class */
|
||||||
|
.highlight .vg { color: #003333 } /* Name.Variable.Global */
|
||||||
|
.highlight .vi { color: #003333 } /* Name.Variable.Instance */
|
||||||
|
.highlight .il { color: #FF6600 } /* Literal.Number.Integer.Long */
|
||||||
|
|
||||||
|
.type-csharp .highlight .k { color: #0000FF }
|
||||||
|
.type-csharp .highlight .kt { color: #0000FF }
|
||||||
|
.type-csharp .highlight .nf { color: #000000; font-weight: normal }
|
||||||
|
.type-csharp .highlight .nc { color: #2B91AF }
|
||||||
|
.type-csharp .highlight .nn { color: #000000 }
|
||||||
|
.type-csharp .highlight .s { color: #A31515 }
|
||||||
|
.type-csharp .highlight .sc { color: #A31515 }
|
427
stylesheets/stylesheet.css
Normal file
427
stylesheets/stylesheet.css
Normal file
|
@ -0,0 +1,427 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
Slate Theme for GitHub Pages
|
||||||
|
by Jason Costello, @jsncostello
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@import url(pygment_trac.css);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
MeyerWeb Reset
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe,
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
|
a, abbr, acronym, address, big, cite, code,
|
||||||
|
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||||
|
small, strike, strong, sub, sup, tt, var,
|
||||||
|
b, u, i, center,
|
||||||
|
dl, dt, dd, ol, ul, li,
|
||||||
|
fieldset, form, label, legend,
|
||||||
|
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||||
|
article, aside, canvas, details, embed,
|
||||||
|
figure, figcaption, footer, header, hgroup,
|
||||||
|
menu, nav, output, ruby, section, summary,
|
||||||
|
time, mark, audio, video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article, aside, details, figcaption, figure,
|
||||||
|
footer, header, hgroup, menu, nav, section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote, q {
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
Theme Styles
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
body {
|
||||||
|
box-sizing: border-box;
|
||||||
|
color:#373737;
|
||||||
|
background: #212121;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
margin: 10px 0;
|
||||||
|
font-weight: 700;
|
||||||
|
color:#222222;
|
||||||
|
font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
font-size: 32px;
|
||||||
|
background: url('../images/bg_hr.png') repeat-x bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 10px 0 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer p {
|
||||||
|
color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #007edf;
|
||||||
|
text-shadow: none;
|
||||||
|
|
||||||
|
transition: color 0.5s ease;
|
||||||
|
transition: text-shadow 0.5s ease;
|
||||||
|
-webkit-transition: color 0.5s ease;
|
||||||
|
-webkit-transition: text-shadow 0.5s ease;
|
||||||
|
-moz-transition: color 0.5s ease;
|
||||||
|
-moz-transition: text-shadow 0.5s ease;
|
||||||
|
-o-transition: color 0.5s ease;
|
||||||
|
-o-transition: text-shadow 0.5s ease;
|
||||||
|
-ms-transition: color 0.5s ease;
|
||||||
|
-ms-transition: text-shadow 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main_content a:hover {
|
||||||
|
color: #0069ba;
|
||||||
|
text-shadow: #0090ff 0px 0px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a:hover {
|
||||||
|
color: #43adff;
|
||||||
|
text-shadow: #0090ff 0px 0px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
position: relative;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 739px;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 10px 0 10px 0;
|
||||||
|
border: 1px solid #ebebeb;
|
||||||
|
|
||||||
|
box-shadow: 0 0 5px #ebebeb;
|
||||||
|
-webkit-box-shadow: 0 0 5px #ebebeb;
|
||||||
|
-moz-box-shadow: 0 0 5px #ebebeb;
|
||||||
|
-o-box-shadow: 0 0 5px #ebebeb;
|
||||||
|
-ms-box-shadow: 0 0 5px #ebebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code {
|
||||||
|
width: 100%;
|
||||||
|
color: #222;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
border-radius: 2px;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
-webkit-border-radius: 2px;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,.1);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: 3px;
|
||||||
|
margin: 0 3px;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre code {
|
||||||
|
display: block;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 0 0 0 20px;
|
||||||
|
border-left: 3px solid #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol, dl {
|
||||||
|
margin-bottom: 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
list-style: inside;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
list-style: decimal inside;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl dd {
|
||||||
|
padding-left: 20px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl p {
|
||||||
|
padding-left: 20px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
height: 1px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border: none;
|
||||||
|
background: url('../images/bg_hr.png') repeat-x center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: 1px solid #373737;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
|
padding: 10px;
|
||||||
|
background: #373737;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #373737;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
background: #f2f2f2;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
Full-Width Styles
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
.outer {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
position: relative;
|
||||||
|
max-width: 640px;
|
||||||
|
padding: 20px 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#forkme_banner {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
right: 10px;
|
||||||
|
z-index: 10;
|
||||||
|
padding: 10px 50px 10px 10px;
|
||||||
|
color: #fff;
|
||||||
|
background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%;
|
||||||
|
font-weight: 700;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,.5);
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header_wrap {
|
||||||
|
background: #212121;
|
||||||
|
background: -moz-linear-gradient(top, #373737, #212121);
|
||||||
|
background: -webkit-linear-gradient(top, #373737, #212121);
|
||||||
|
background: -ms-linear-gradient(top, #373737, #212121);
|
||||||
|
background: -o-linear-gradient(top, #373737, #212121);
|
||||||
|
background: linear-gradient(top, #373737, #212121);
|
||||||
|
}
|
||||||
|
|
||||||
|
#header_wrap .inner {
|
||||||
|
padding: 50px 10px 30px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#project_title {
|
||||||
|
margin: 0;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 42px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-shadow: #111 0px 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#project_tagline {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 300;
|
||||||
|
background: none;
|
||||||
|
text-shadow: #111 0px 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#downloads {
|
||||||
|
position: absolute;
|
||||||
|
width: 210px;
|
||||||
|
z-index: 10;
|
||||||
|
bottom: -40px;
|
||||||
|
right: 0;
|
||||||
|
height: 70px;
|
||||||
|
background: url('../images/icon_download.png') no-repeat 0% 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zip_download_link {
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
width: 90px;
|
||||||
|
height:70px;
|
||||||
|
text-indent: -5000px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: url(../images/sprite_download.png) no-repeat bottom left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tar_download_link {
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
width: 90px;
|
||||||
|
height:70px;
|
||||||
|
text-indent: -5000px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: url(../images/sprite_download.png) no-repeat bottom right;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zip_download_link:hover {
|
||||||
|
background: url(../images/sprite_download.png) no-repeat top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tar_download_link:hover {
|
||||||
|
background: url(../images/sprite_download.png) no-repeat top right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main_content_wrap {
|
||||||
|
background: #f2f2f2;
|
||||||
|
border-top: 1px solid #111;
|
||||||
|
border-bottom: 1px solid #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main_content {
|
||||||
|
padding-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer_wrap {
|
||||||
|
background: #212121;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
Small Device Styles
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@media screen and (max-width: 480px) {
|
||||||
|
body {
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#downloads {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
min-width: 320px;
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#project_title {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
code, pre {
|
||||||
|
min-width: 320px;
|
||||||
|
max-width: 480px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue