I came across fiddling with torcs for a while for self-driving tests. In some case, I need to reset the car to the middle of the track when stuck. After some trial and error and studying into the code, I found out that the tCar
struct always records the closest main part of the track in trkPos
, albeit the car might be in the rside
and lside
segments attached to the track. So generally, one section of a track consists of main road, left side and right side, left border and right border. Their composition is as follows,
Coding Beast's Manual
Monday, July 24, 2017
TORCS: Track and Segments
Monday, June 13, 2016
Image Processing - Histogram Equalization - Part 2
Draw Histograms
# draw flattened histogram import matplotlib.pyplot as plt import numpy as np from PIL import Image %matplotlib inline im = Image.open("sample.jpg") im_arr = np.array(im) print im_arr.shape plt.figure(figsize=(15,5)) plt.subplot(1,2,1) plt.imshow(im_arr) plt.axis('off') plt.subplot(1,2,2) im_r = im_arr[:,:,0].flatten() # 3d (r,g,b) to 1d (stacked) im_g = im_arr[:,:,1].flatten() im_b = im_arr[:,:,2].flatten() imhist, bins = np.histogram(im_r, 256, normed=True) #bins are a sequence of data range plt.plot(imhist, label="Red") imhist, bins = np.histogram(im_g, 256, normed=True) plt.plot(imhist, label="Green") imhist, bins = np.histogram(im_b, 256, normed=True) plt.plot(imhist, label="Blue") plt.legend(loc=1)
Histogram Equalization on Grayscale Image
# histogram equalization def histeq(im, nbr_bins=256): imhist,bins = np.histogram(im.flatten(),nbr_bins,normed=True) cdf = imhist.cumsum() # cumulative distribution function (cumulative sum) cdf = 255 * cdf / cdf[-1] # normalization (brilliant! cdf[-1] is the sum of all) im2 = np.interp(im.flatten(), bins[:-1], cdf) # (x', x, fx) linear interpolate x' accordingg to x -> f(x) return im2.reshape(im.shape), cdf im_gray = np.array(im.convert('L')) # interpolate in grayscale im2, cdf = histeq(im_gray) # increase the dark area plt.figure(figsize=(15,10)) plt.subplot(2,2,1) plt.imshow(im_gray,cmap='gray') plt.subplot(2,2,2) plt.imshow(im2,cmap='gray') plt.subplot(2,2,3) plt.plot(cdf, label="Cumulative Distribution Function") plt.legend(loc=2) imhist2, bins2 = np.histogram(im2, 256, normed=True) plt.subplot(2,2,4) plt.plot(imhist2, label="Equalized Historgram") plt.legend(loc=1)
Histogram Equalization on Colored Image
im = Image.open("Luncheon.jpg") im_arr = np.array(im) img_r = im_arr[:,:,0] img_g = im_arr[:,:,1] img_b = im_arr[:,:,2] im_r_eq, cdf = histeq(img_r) im_g_eq, cdf = histeq(img_g) im_b_eq, cdf = histeq(img_b) im_eq = np.zeros(im_arr.shape, 'uint8') print im_r_eq.shape im_eq[:,:,0] = im_r_eq im_eq[:,:,1] = im_g_eq im_eq[:,:,2] = im_b_eq print im_eq.shape plt.figure(figsize=(15,10)) plt.subplot(2,3,1) plt.imshow(im_r_eq, cmap="gray") plt.axis('off') plt.subplot(2,3,2) plt.imshow(im_g_eq, cmap="gray") plt.axis('off') plt.subplot(2,3,3) plt.imshow(im_b_eq, cmap="gray") plt.axis('off') ime = Image.fromarray(im_eq) plt.subplot(2,3,4) plt.imshow(ime) plt.axis('off') plt.subplot(2,3,5) plt.imshow(im) plt.axis('off')
Monday, June 6, 2016
Matplotlib: Image Processing - Part 1
Remapping Images
from PIL import Image import numpy as np import matplotlib.pyplot as plt %matplotlib inline n_row, n_col = 1, 5 plt.figure(figsize=(n_col*3,n_row*3),dpi=100) img = Image.open("sample.jpg") plt.subplot(n_row, n_col, 1) plt.imshow(img) plt.axis('off') # gray img2 = np.array(img.convert('L')) plt.subplot(n_row, n_col, 2) plt.imshow(img2, cmap='gray') plt.axis('off') # inverse img3 = 255 - img2 plt.subplot(n_row, n_col, 3) plt.imshow(img3, cmap='gray') plt.axis('off') # map to 100 ... 200 img4 = (100.0/255)*img2 + 100 plt.subplot(n_row, n_col, 4) plt.imshow(img4, cmap='gray') plt.axis('off') # squared img5 = 255.0 * (img2/255.0) **2 plt.subplot(n_row, n_col, 5) plt.imshow(img5, cmap='gray') plt.axis('off')
Plot multiple functions together
from PIL import Image import numpy as np import matplotlib.pyplot as plt %matplotlib inline f1 = np.array(range(255)) # f1 = np.linspace(0,255,255,endpoint=True) f2 = 255 - f1 f3 = (100.0/255)*f1 + 100 f4 = 255.0*(f1/255.0)**2 plt.figure(figsize=(8,5)) plt.plot(f1,f1,label="f(x)=x") plt.plot(f1,f2,label="f(x)=255-x") plt.plot(f1,f3,label="f(x)=(100.0/255)*x + 100") plt.plot(f1,f4,label="f(x)=255.0*(x/255.0)**2") plt.axis([0,260, 0, 260]) plt.legend(loc=2) print min(f1), max(f1) print min(f2), max(f2) print min(f3), max(f3) print min(f4), max(f4)
Tuesday, March 11, 2014
XSLT: Structuring Data in Attributes or in Child Elements
We are free to select tags to our liking, so are to build an XML structure, whether it is element-based, where there is almost no attributes in the XML tree (see the following exmample) or attribute-based (converted by XSLT code to be shown below).
<?xml version="1.0" encoding="UTF-8"?> <catalog> <cd> <title>Empire Burlesque</title> <artist>Bob Dylan</artist> <country>USA</country> <company>Columbia</company> <price>10.90</price> <year>1985</year> </cd> <cd> <title>Hide your heart</title> <artist>Bonnie Tyler</artist> <country>UK</country> <company>CBS Records</company> <price>9.90</price> <year>1988</year> </cd> <cd> <title>Greatest Hits</title> <artist>Dolly Parton</artist> <country>USA</country> <company>RCA</company> <price>9.90</price> <year>1982</year> </cd> <cd> <title>Still got the blues</title> <artist>Gary Moore</artist> <country>UK</country> <company>Virgin records</company> <price>10.20</price> <year>1990</year> </cd> <cd> <title>Eros</title> <artist>Eros Ramazzotti</artist> <country>EU</country> <company>BMG</company> <price>9.90</price> <year>1997</year> </cd> <cd> <title>One night only</title> <artist>Bee Gees</artist> <country>UK</country> <company>Polydor</company> <price>10.90</price> <year>1998</year> </cd> <cd> <title>Sylvias Mother</title> <artist>Dr.Hook</artist> <country>UK</country> <company>CBS</company> <price>8.10</price> <year>1973</year> </cd> <cd> <title>Maggie May</title> <artist>Rod Stewart</artist> <country>UK</country> <company>Pickwick</company> <price>8.50</price> <year>1990</year> </cd> <cd> <title>Romanza</title> <artist>Andrea Bocelli</artist> <country>EU</country> <company>Polydor</company> <price>10.80</price> <year>1996</year> </cd> <cd> <title>When a man loves a woman</title> <artist>Percy Sledge</artist> <country>USA</country> <company>Atlantic</company> <price>8.70</price> <year>1987</year> </cd> <cd> <title>Black angel</title> <artist>Savage Rose</artist> <country>EU</country> <company>Mega</company> <price>10.90</price> <year>1995</year> </cd> <cd> <title>1999 Grammy Nominees</title> <artist>Many</artist> <country>USA</country> <company>Grammy</company> <price>10.20</price> <year>1999</year> </cd> <cd> <title>For the good times</title> <artist>Kenny Rogers</artist> <country>UK</country> <company>Mucik Master</company> <price>8.70</price> <year>1995</year> </cd> <cd> <title>Big Willie style</title> <artist>Will Smith</artist> <country>USA</country> <company>Columbia</company> <price>9.90</price> <year>1997</year> </cd> <cd> <title>Tupelo Honey</title> <artist>Van Morrison</artist> <country>UK</country> <company>Polydor</company> <price>8.20</price> <year>1971</year> </cd> <cd> <title>Soulsville</title> <artist>Jorn Hoel</artist> <country>Norway</country> <company>WEA</company> <price>7.90</price> <year>1996</year> </cd> <cd> <title>The very best of</title> <artist>Cat Stevens</artist> <country>UK</country> <company>Island</company> <price>8.90</price> <year>1990</year> </cd> <cd> <title>Stop</title> <artist>Sam Brown</artist> <country>UK</country> <company>A and M</company> <price>8.90</price> <year>1988</year> </cd> <cd> <title>Bridge of Spies</title> <artist>T`Pau</artist> <country>UK</country> <company>Siren</company> <price>7.90</price> <year>1987</year> </cd> <cd> <title>Private Dancer</title> <artist>Tina Turner</artist> <country>UK</country> <company>Capitol</company> <price>8.90</price> <year>1983</year> </cd> <cd> <title>Midt om natten</title> <artist>Kim Larsen</artist> <country>EU</country> <company>Medley</company> <price>7.80</price> <year>1983</year> </cd> <cd> <title>Pavarotti Gala Concert</title> <artist>Luciano Pavarotti</artist> <country>UK</country> <company>DECCA</company> <price>9.90</price> <year>1991</year> </cd> <cd> <title>The dock of the bay</title> <artist>Otis Redding</artist> <country>USA</country> <company>Atlantic</company> <price>7.90</price> <year>1987</year> </cd> <cd> <title>Picture book</title> <artist>Simply Red</artist> <country>EU</country> <company>Elektra</company> <price>7.20</price> <year>1985</year> </cd> <cd> <title>Red</title> <artist>The Communards</artist> <country>UK</country> <company>London</company> <price>7.80</price> <year>1987</year> </cd> <cd> <title>Unchain my heart</title> <artist>Joe Cocker</artist> <country>USA</country> <company>EMI</company> <price>8.20</price> <year>1987</year> </cd> </catalog>
With the help of XSLT, we can easily transform element-based data into attribute-based data. Several points to notice in the XSLT code:
- child selector
child::
- element name
name()
- element text
text()
- dynamic attribute name
{name()}
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <catalog> <xsl:for-each select="catalog/cd"> <cd> <xsl:for-each select="child::*"> <xsl:attribute name="{name(.)}"> <xsl:value-of select="text()"/> </xsl:attribute> </xsl:for-each> </cd> </xsl:for-each> </catalog> </xsl:template> </xsl:stylesheet>
Result: the attribute-based data.
<catalog> <cd title="Empire Burlesque" artist="Bob Dylan" country="USA" company="Columbia" price="10.90" year="1985" /> <cd title="Hide your heart" artist="Bonnie Tyler" country="UK" company="CBS Records" price="9.90" year="1988" /> <cd title="Greatest Hits" artist="Dolly Parton" country="USA" company="RCA" price="9.90" year="1982" /> <cd title="Still got the blues" artist="Gary Moore" country="UK" company="Virgin records" price="10.20" year="1990" /> <cd title="Eros" artist="Eros Ramazzotti" country="EU" company="BMG" price="9.90" year="1997" /> <cd title="One night only" artist="Bee Gees" country="UK" company="Polydor" price="10.90" year="1998" /> <cd title="Sylvias Mother" artist="Dr.Hook" country="UK" company="CBS" price="8.10" year="1973" /> <cd title="Maggie May" artist="Rod Stewart" country="UK" company="Pickwick" price="8.50" year="1990" /> <cd title="Romanza" artist="Andrea Bocelli" country="EU" company="Polydor" price="10.80" year="1996" /> <cd title="When a man loves a woman" artist="Percy Sledge" country="USA" company="Atlantic" price="8.70" year="1987" /> <cd title="Black angel" artist="Savage Rose" country="EU" company="Mega" price="10.90" year="1995" /> <cd title="1999 Grammy Nominees" artist="Many" country="USA" company="Grammy" price="10.20" year="1999" /> <cd title="For the good times" artist="Kenny Rogers" country="UK" company="Mucik Master" price="8.70" year="1995" /> <cd title="Big Willie style" artist="Will Smith" country="USA" company="Columbia" price="9.90" year="1997" /> <cd title="Tupelo Honey" artist="Van Morrison" country="UK" company="Polydor" price="8.20" year="1971" /> <cd title="Soulsville" artist="Jorn Hoel" country="Norway" company="WEA" price="7.90" year="1996" /> <cd title="The very best of" artist="Cat Stevens" country="UK" company="Island" price="8.90" year="1990" /> <cd title="Stop" artist="Sam Brown" country="UK" company="A and M" price="8.90" year="1988" /> <cd title="Bridge of Spies" artist="T`Pau" country="UK" company="Siren" price="7.90" year="1987" /> <cd title="Private Dancer" artist="Tina Turner" country="UK" company="Capitol" price="8.90" year="1983" /> <cd title="Midt om natten" artist="Kim Larsen" country="EU" company="Medley" price="7.80" year="1983" /> <cd title="Pavarotti Gala Concert" artist="Luciano Pavarotti" country="UK" company="DECCA" price="9.90" year="1991" /> <cd title="The dock of the bay" artist="Otis Redding" country="USA" company="Atlantic" price="7.90" year="1987" /> <cd title="Picture book" artist="Simply Red" country="EU" company="Elektra" price="7.20" year="1985" /> <cd title="Red" artist="The Communards" country="UK" company="London" price="7.80" year="1987" /> <cd title="Unchain my heart" artist="Joe Cocker" country="USA" company="EMI" price="8.20" year="1987" /> </catalog>
Friday, March 7, 2014
VBScript: Dynamically Create GUIDs
Function CreateGUID() Set TypeLib = CreateObject("Scriptlet.TypeLib") myGuid = CStr(TypeLib.Guid) CreateGUID = Left(myGuid, Len(myGuid)-2) Set TypeLib = Nothing End Function
Wednesday, February 12, 2014
Windows Installer: Migrating From InstallShield to WiX
Notice: I've prepared my scripts into this repository github: IS2WiX [5].
Preparation
Installing WiX Toolset will get you all the tools to compile all XML files in your WiX project. It will also install templates to Visual Studio and VS does automatically configure compilation options for you.
We need programming knowledge from XSLT/XPATH to operate on XML files, also some VB.NET knowledge to write customized custom actions.
Here is a list of all related tools and languages.
- WiX Toolset[1], documentation
- Visual Studio 2012
- Microsoft SDK (Orca.exe, Wilogutl.exe etc.[2])
- XSLT, XPath, XML
- VB.NET Custom Actions
- InstallShield, Help file
- Your InstallShield project file and Internet Explorer[3]
The Idea
WiX and InstallShield are tools to make .msi
packages, they all base on Microsoft Windows Installer technology. They all use .xml
files to represent their project, where .xml
is either handcrafted or auto-generated from parameters set from a graphic interface. So to build a bridge between the two, we seek XSLT
for help.
Example
Your Binary table shall look similar to this.<table name="Binary"> <col key="yes" def="s72">Name</col> <col def="V0">Data</col> <col def="S255">ISBuildSourcePath</col> <row><td>ISLockPermissions.dll</td><td/><td>[ISProductFolder]\redist\Language Independent\i386\ISLockPermissions.dll</td></row> <row><td>ISSCHRPL.DLL</td><td/><td>[ISProductFolder]\redist\language independent\i386\isschrpl.dll</td></row> <row><td>ISSetup.dll</td><td/><td>[ISProductFolder]\redist\language independent\i386\ISSetup.dll</td></row> ... </table>
Let's write a stylesheet to convert the above table to WiX format,
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" /> <xsl:template match="/"> <xsl:for-each select="/table/row"> <Binary> <xsl:attribute name="Id"> <xsl:value-of select="td[1]" /></xsl:attribute> <xsl:attribute name="SourceFile"> <xsl:value-of select="td[3]" /></xsl:attribute> </Binary> </xsl:for-each> </xsl:template> </xsl:stylesheet>
The output shall look like,
<Binary Id="ISLockPermissions.dll" SourceFile="[ISProductFolder]\redist\Language Independent\i386\ISLockPermissions.dll" /> <Binary Id="ISSCHRPL.DLL" SourceFile="[ISProductFolder]\redist\language independent\i386\isschrpl.dll" /> <Binary Id="ISSetup.dll" SourceFile="[ISProductFolder]\redist\language independent\i386\ISSetup.dll" />
View the InstallShield Project
Your project is composed of tables. With the help of stylesheet written inis.xsl
[4], you could have a direct view of all these tables.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml-stylesheet type="text/xsl" href="is.xsl" ?>
From InstallShiled MSI tables to WiX
One can search help files provided by WiX to study how it is really mapped. The following is an incomplete list collected while I was working on a migration project.
IS/MSI | WiX Element | Parent | |
---|---|---|---|
ActionText | ProgressText | UI | |
AdminExecuteSequence | AdminExecuteSequence | Fragment | |
AdminUISequence | AdminUISequence | Fragment | |
AdvtExecuteSequence | AdvertiseExecuteSequence | Product | |
AppSearch | DirectorySearch | Property | |
Binary | Binary | Fragment | |
CheckBox | Control Type="CheckBox" CheckBoxValue="" | Dialog | |
Component | Component | Fragment, Directory | |
Control | Control | Dialog | |
ControlCondition | Condition | Control | |
ControlEvent | Publish | UI | |
CreateFolder | CreateFolder | Directory | |
CustomAction | CustomAction | Fragment | |
Dialog | Dialog | UI | |
Directory | Directory | Directoryref, Fragment | |
DrLocator | DirectorySearch | Property | |
Error | Error | UI | |
EventMapping | Subscribe | Control | |
Feature | Feature | FeatureGroup, Fragment | |
FeatureComponents | FeatureRef, ComponentRef, ComponentGroupRef | Fragment | |
File | File | Component | |
Font | File TrueType=yes | Component | |
ISString | String | WixLocalization | |
Icon | Icon | Shortcut | |
InstallExecuteSequence | InstallExecuteSequence | Product | |
InstallUISequence | InstallUISequence | UI | |
Property | Property | Product | |
RadioButton | RadioButton, RadioButtonGroup | Control | |
Registry | Registry | Component | |
ServiceControl | ServiceControl | Component | |
ServiceInstall | ServiceInstall | Component | |
Shortcut | Shortcut | Component | |
TextStyle | TextStyle | UI | |
UIText | UIText | UI | |
Upgrade | Upgrade, UpgradeVersion | Product |
Footnote
- WiX Toolset
- Windows Installer Development Tools
- Chrome will have problems viewing an
.xml
file referencing another.xsl
file locally due to the cross-origin security issue. - By default, the stylesheet file should be at
C:\Program Files (x86)\InstallShield\2011\Support\is.xsl
- Github: IS2WiX
Triassic Skills
Blog Archive
Myriad
XSLT Tags
- xsl:apply-template
- xsl:apply-templates
- xsl:attribute
- xsl:apply-imports
- xsl:attribute-set
- xsl:choose
- xsl:copy
- xsl:for-each
- xsl:decimal-format
- xsl:element
- xsl:fallback
- xsl:if
- xsl:import
- xsl:include
- xsl:key
- xsl:message
- xsl:namespace-alias
- xsl:number
- xsl:otherwise
- xsl:output
- xsl:param
- xsl:preserve-space
- xsl:strip-space
- xsl:stylesheet
- xsl:template
- xsl:transform
- xsl:text
- xsl:value-of
- xsl:variable
- xsl:when
- xsl:with-param
- xsl:
XSLT Data Types
XSLT Expressions
XSLT Patterns
Windows Console Commands
-
assign
attrib
backup
break
cd
cd..
chdir
chkdsk
cls
cmd
color
command
comp
copy
ctty
date
defrag
del
deltree
dir
diskcomp
diskcopy
doskey
echo
edit
edlin
emm386
erase
exe2bin
exit
expand
fastopen
fc
fdisk
find
for
format
goto
graftabl
help
hexdump
hostname
if
if
ipconfig
join
keyb
label
md
mem
mode
more
nomefile
path
pause
print
prompt
rd
recover
rem
ren
replace
restore
rmdir
select
set
share
shift
sort
subst
sys
time
tree
type
undelete
unformat
ver
verify
vol
xcopy
[comando]/?