FLOSS Project Planets

TC Drupal News: Session Recordings Available

Planet Drupal - Mon, 2019-06-17 16:01

As we do every year, videos of all the 2019 Twin Cities Drupal Camp sessions are now available on our YouTube channel. Special thanks to Kevin Thull for recording and publishing them all!

Watch the videos online for free, and be sure to follow @tcdrupal on Twitter for updates in the future.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36820-coque serpent iphone x-qxsngw

Planet Python - Mon, 2019-06-17 12:31

Coque iphone 7 pinguoin Coque iphone 6 resistance ‘Cela montre simplement que tout peut arriver à Londres.’ Les gens étaient gênés et semblaient l’ignorer. Personne ne voulait regarder dans les yeux. Par exemple, Les gens…

The post 12-34-36820-coque serpent iphone x-qxsngw appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36819-coque appel pour iphone xr-vseqby

Planet Python - Mon, 2019-06-17 12:31

Coque citation iphone x Coque iphone 6 pylone Lorsque vous envisagez sérieusement de disposer de frais très intéressants, cherchez généralement EDUP EP B3502 Car Audio-RCA HiFi AMP Récepteur de musique Bluetooth A2DP Pour Apple iPod…

The post 12-34-36819-coque appel pour iphone xr-vseqby appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36818-coque double iphone xs max-omqdbv

Planet Python - Mon, 2019-06-17 12:31

Coque iphone 6 plus vitre Coque iphone xs max don t touch my phone Angela Ahrendts, directrice des ventes chez Apple Inc., souhaite mettre fin à la tradition de l’entreprise consistant à faire attendre les…

The post 12-34-36818-coque double iphone xs max-omqdbv appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36817-coque iphone x noir mate spigen-bprslv

Planet Python - Mon, 2019-06-17 12:31

Coque iphone xr automobile Coque iphone xr etuit Je suis abonné à T Mobile. Je vis au centre-ville de Raleigh et je n’ai aucun problème à Raleigh. Si vous n’êtes pas sûr de vos compétences…

The post 12-34-36817-coque iphone x noir mate spigen-bprslv appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36816-iphone x coque rabat-smvadc

Planet Python - Mon, 2019-06-17 12:31

Coque iphone x 8757 Bape coque iphone 7 Je suis un vieil homme, et je préfère les sauvegardes locales que de faire confiance au cloud. LOL Luddite. Canon dévoile le PowerShot G11 compact haut de…

The post 12-34-36816-iphone x coque rabat-smvadc appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36815-coque iphone 7 boruto-nwkevy

Planet Python - Mon, 2019-06-17 12:31

Coque iphone x rino Coque iphone 8 transparente antichoc Chaque kit couvre l’avant et l’arrière du Kindle 2 et comprend un boîtier d’adaptateur d’alimentation. Support adhésif non permanent qui vous permet simplement de décoller les…

The post 12-34-36815-coque iphone 7 boruto-nwkevy appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36814-ocase coque iphone 7-qtsnlc

Planet Python - Mon, 2019-06-17 12:31

Coque iphone 7 plus fcb Coque iphone 8 dont touch my phone rouge GM a déclaré que la Chine était son plus gros marché depuis six ans. Volkswagen a également mis un accent énorme sur…

The post 12-34-36814-ocase coque iphone 7-qtsnlc appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36813-coque iphone xr femme nu-nlkubr

Planet Python - Mon, 2019-06-17 12:31

Coque iphone 6 paillette pas cher Coque iphone 8 plus novago Mais dans la base de données FMC, il s’agissait de Roméo. Leur véritable inconvénient est le manque d’applications. Bien que cela ne doive pas…

The post 12-34-36813-coque iphone xr femme nu-nlkubr appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36812-coque anneau iphone 8 plus rouge-qwcdgl

Planet Python - Mon, 2019-06-17 12:31

Coque sasuke iphone xr Coque iphone 7 handball En tant que 64 bits, il prend en charge une énorme quantité de mémoire virtuelle qui est souvent requise lorsque vous effectuez plusieurs tâches. En règle générale,…

The post 12-34-36812-coque anneau iphone 8 plus rouge-qwcdgl appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36811-coque pour iphone 6 minion-htgbmn

Planet Python - Mon, 2019-06-17 12:30

Coque iphone x framboise Iphone 7 coque camouflage Devenu populaire avec l’invention de l’appareil photo numérique. Chaque semaine, de nouvelles révélations jettent un doute sur ses déclarations selon lesquelles il était innocent. Cela dépend également…

The post 12-34-36811-coque pour iphone 6 minion-htgbmn appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36810-coque aimantee iphone x-hlsytk

Planet Python - Mon, 2019-06-17 12:30

Coque bois iphone 8 Coque apple iphone 6 pas cher Des choses folles, des cerveaux .. Apple iPhone X Blu Vivo 8L vs Lenovo K8 Note Oppo F5 vs Blu Vivo 8L vs.. Matériel vendu…

The post 12-34-36810-coque aimantee iphone x-hlsytk appeared first on Anaconda.

Categories: FLOSS Project Planets

Continuum Analytics Blog: 12-34-36809-coque pour l eau iphone 8-figjxn

Planet Python - Mon, 2019-06-17 12:30

Coque iphone 8 pus Coque iphone xr supreme homme Il n’est généralement pas basé sur le cloud, car la plupart des entreprises sont conscientes de l’importance des programmes de comptabilité et d’inventaire sur site (sécurité…

The post 12-34-36809-coque pour l eau iphone 8-figjxn appeared first on Anaconda.

Categories: FLOSS Project Planets

Emmanuel Kasper: Normalize a bunch of audio files to the same loudness

Planet Debian - Mon, 2019-06-17 10:30
I had a bunch of audio files in a directory, each recorded live with different devices, and it proved very ear-painful to hear the audio files in a playlist because of the difference of loudness.
To normalize audio filesm  you can find a number of tool working with ID3 tags, but after testing with vlc, mplayer, and the pogo mp3 player none of them did produce a measurable change. So I converted everything to wav, normalized the wav files, then converted back to mp3.

delete funny chars and spaces in file names
detox music_dir
converting files to wav is just a matter of
# this uses zsh recursive globbing
for file in **/*.mp3 ; do ffmpeg -i $file  "$(basename $file .mp3).wav"; done
normalizing files with the normalize-audio program, from the debian package of the same name.
# this uses zsh recursive globbing
normalize-audio **/*.wav
converting back to mp3
for file in **/*.wav ; do ffmpeg -b:a 192k -acodec libmp3lame -i $file "$(basename $file .wav).mp3"; done
Categories: FLOSS Project Planets

Real Python: Python Community Interview With Marlene Mhangami

Planet Python - Mon, 2019-06-17 10:00

We are joined today by Marlene Mhangami. Marlene is a passionate Pythonista who is not only using tech to facilitate social change and empower Zimbabwean women but is also the chair of the very first PyCon Africa. Join me as we talk about her non-traditional start in tech, as well as her passion for using technology to create social change for good.

Ricky: Welcome, Marlene! I’m so glad you could join me for this interview. Let’s start with the usual first question. How’d you get into programming, and when did you start using Python?

Marlene: Well, my background is in molecular biology, so in college, although I had some interaction with code, it wasn’t really something I used regularly. I’ve always been interested in technology and the impact it has on the world, but growing up I didn’t really have anyone to introduce me to the concept of coding. We had one computer that we shared in my house, and my brothers were super into gaming. They were on it all the time.

In high school, I took a computer class, but my teachers, who I’m sure were really nice people, didn’t go much further than the basics of using Microsoft Office and having us memorize names of different parts of hardware. So, in general, I focused more on life and physical sciences, and I’m still really interested in those fields today.

I studied for a bit in the United States for college, and I remember coming home one summer and being really aware of how different Zimbabwe was from the U.S. From really small cultural differences like how people address conflict (which is something I’m still trying to figure out with my US friends) to much more impactful things like access to knowledge and education.

I decided I wanted to start being more involved with my local community, and for some reason, I decided that I wanted to leverage technology to help me do that. I also had a really vivid dream that made me re-evaluate what I was doing with my life.

After googling around and actually organizing a meetup, I got introduced to one of my co-founders, Ronald Maravanykia, who was at the time running a Django girls workshop in Harare. He introduced me to Python as a great educational tool for teaching programming to people who don’t have a computer science background. That was almost three years ago, and I’m super grateful Python ended up being the language I chose to focus on. It’s really great!

Ricky: As a Zimbabwean, you are passionate about empowering Zimbabwean women in tech and helping today’s young girls pursue a career in tech. So much so that you are the programs director at the non-profit ZimboPy?

Marlene: Yes, as I mentioned earlier, using technology to create social change for good is something that’s consistently at the forefront of my mind. My co-founders and I decided to create ZimboPy as a way to give girls in Zim access to knowledge and experiences they wouldn’t necessarily get anywhere else in the country.

I think for me, the end goal is to create a model where we introduce girls to programming, and if they enjoy it, offering them a pathway to get jobs in the field. The tech world is not perfect, but unlike most fields, there are ways that you can by-pass traditional gatekeepers and be successful regardless of whether or not you have the privilege of receiving formal higher education.

We are still a small non-profit, and I’m learning new things every day, but we’ve had some great success stories that give me so much hope! Also, our mentorship weeks, where we introduce girls to women who are doing incredible things in the field and help them build something new, are my favorite thing to do all year! We’ve had incredible women like Ashley McNamara and Emily Freeman speak. It’s always so much fun!

Ricky: You are one of the 13 members of the Python Software Foundation’s (PSF) Board of Directors. How did you come to be involved with the PSF, and what do you think is the biggest challenge as we look towards 2020 and beyond?

Marlene: I’m actually up for re-election this year, so hopefully, I’ll still be on the board for 2020. I really had such a positive experience with it so far!

I was actually introduced to the PSF by Lorena Mesa, who was volunteering to speak at one of our ZimboPy mentorship weeks in early 2017. She was on the board at the time, and we spoke about it around the time when elections were coming up. She really felt that I would be a great addition to the board. At that time, no one from Africa had ever held a seat, so she was super encouraging.

I remember looking through the list of the nominees and thinking that I didn’t belong there. I had done some work with the local Python community in Zimbabwe, but I felt really intimidated by everyone’s profiles. I ended up agreeing to let Lorena nominate me, mainly because I had nothing to lose, haha! Surprisingly, I was voted in, which I think is purely a testament to the Python community’s commitment to diversity and global representation.

So many changes have taken place in the last few years: the formation of the steering council, the exponential growth of PyCon, and the spread of the language globally. All of these are things we’ve been able to discuss as a board.

I think defining the biggest challenge is tricky because it genuinely depends on each individual’s perspective. There are Directors on the board who are infinitely more technical than I am, and they can probably speak to all sorts of challenges on the future of Python from a more technical perspective.

For me, my focus is to help the growth of Python and its community to be as inclusive and representative as possible. I recently became the board’s communications co-chair, along with Lorena, and have been working with the blogging team. I’d like to see an increase in the representation of voices from communities around the world, maybe one day having blog posts and content on the official site in various languages.

All of these are things I feel are important and a challenge that we have to tackle well.

Ricky: I had the good fortune to meet you in person at PyCon 2019. It was your first PyCon (mine, too). How was your experience there? What was the standout moment for you?

Marlene: I genuinely loved Pycon 2019, and of course meeting you, Ricky, and the rest of the Real Python team! I’ve been to several PyCons around Africa and other parts of the world, but PyCon US is definitely a unique experience.

One of my favorite things about the conference was how friendly and laid back everyone was. I’d literally pass by people that I follow on Twitter, who have done amazing things, and they’d just be sitting there, eating a sandwich! I’m being a little funny here, but honestly, everyone was so welcoming and fun. I still can’t fully wrap my head around it.

I had so many standout moments, but I think I’d say Sha Wallace and Jessica Meckeller’s joint keynote was out of this world. I was tearing up because it’s such a great example of how we as a community can create positive change! I took away so many notes from that talk that I’d like to implement here in Zimbabwe.

This is an additional thing, I know, but I’d also like to say that I had so many standout moments outside the convention center, like having dinner with people from around the world and going to the local art gallery and trying bubble tea, also generally just wandering about the city. I had the best time, and I’m really looking forward to Pittsburg in 2020!

Ricky: If my memory serves right, at the end of PyCon, Microsoft and Adafruit donated a bunch of Circuit Playground Lunchbox Kits for you to take back to the girls you mentor in Zimbabwe. I’m curious if you managed to put them to use yet? Or what your plans are, outside of using them to teach them how to write some CircuitPython?

Marlene: Yes! That was another standout moment (to add to the twenty others above, haha). I got to chat with Nina Zakharenko and Katni from Adafruit, who are some of the loveliest human beings I’ve ever met! We had dinner together at some point and afterwards, they decided to donate the kits for me to bring back home and use for our ZimboPy programs.

I only recently got back to Zimbabwe, and I’ve started to play around with the kits myself. The plan at the moment is to host a workshop specifically centered around CircuitPython to show the girls that they can be playful and have fun while they code. I’m super pumped about it!

I was also talking to Kat about the potential of me hosting a tutorial at PyCon Africa with the Adafruit boards, similar to what she was demoing at the Microsoft booth. If I feel confident enough to do it by July, I think that’s something attendees at the conference should look out for!

Ricky: As if all the community work you do already isn’t enough, you’re also the organizer of the very first PyCon Africa! How’s the planning coming on? Can you share any details?

Marlene: I’m really excited that we’re in the final stages of planning for the conference. PyCon Africa is the first regional / pan-African gathering of the Python community! We have a great organizing committee, with people who have helped organize PyCons in Nigeria, Ghana, Namibia, Uganda, South Africa, and even the UK, so in that respect, I’ve been really lucky to land on this team.

The response from the global Python community has also been really encouraging. Real Python is actually one of our sponsors, which is amazing. Shout out to you! I think we’re moving in the right direction.

I’m this year’s chair, and although everything is running smoothly so far, I’ve been surprised by how all-consuming the process of planning can feel at times. Each time I look up it’s as if 3 months have passed! At PyCon US, I was speaking to a few other regional conference organizers and was glad to find I wasn’t the only one that felt like this. It can feel pretty overwhelming sometimes, but for the most part, I’m happy with the progress we’ve made and optimistic that we will put on a great event!

The conference is going to be held in Accra, Ghana, this year from August 6 to 10. We’re looking for sponsors, and there’s an option for individuals to buy a sharing ticket to sponsor a Pythonista who doesn’t have the means to buy their own ticket! You can find out more info on all this on our website: africa.pycon.org

Ricky: Now for my last questions. What else do you get up to in your spare time? Any other hobbies and interests, aside from Python and coding?

Marlene: I really enjoy long walks on the beach, haha. I’m joking, but I also genuinely do! I’ve been getting into running recently, and I’m hoping to try to get myself into good enough form to do a marathon at some point.

I also really like painting, but not in a cultured, cool way. I sometimes just like to paint and draw as a way to relax. Meditation and gratefulness journaling is also something I like to do each morning, as a good way to start the day.

It was an absolute pleasure speaking to Marlene. If you want to attend PyCon Africa, tickets are still available. If you want to find out more about Marlene, or reach out to her and discuss any of the amazing things she is doing, then you can find her on Twitter.

[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

Categories: FLOSS Project Planets

GNU Guix: Substitutes are now available as lzip

GNU Planet! - Mon, 2019-06-17 08:30

For a long time, our build farm at ci.guix.gnu.org has been delivering substitutes (pre-built binaries) compressed with gzip. Gzip was never the best choice in terms of compression ratio, but it was a reasonable and convenient choice: it’s rock-solid, and zlib made it easy for us to have Guile bindings to perform in-process compression in our multi-threaded guix publish server.

With the exception of building software from source, downloads take the most time of Guix package upgrades. If users can download less, upgrades become faster, and happiness ensues. Time has come to improve on this, and starting from early June, Guix can publish and fetch lzip-compressed substitutes, in addition to gzip.


Lzip is a relatively little-known compression format, initially developed by Antonio Diaz Diaz ca. 2013. It has several C and C++ implementations with surprisingly few lines of code, which is always reassuring. One of its distinguishing features is a very good compression ratio with reasonable CPU and memory requirements, according to benchmarks published by the authors.

Lzlib provides a well-documented C interface and Pierre Neidhardt set out to write bindings for that library, which eventually landed as the (guix lzlib) module.

With this in place we were ready to start migrating our tools, and then our build farm, to lzip compression, so we can all enjoy smaller downloads. Well, easier said than done!


The compression format used for substitutes is not a core component like it can be in “traditional” binary package formats such as .deb since Guix is conceptually a “source-based” distro. However, deployed Guix installations did not support lzip, so we couldn’t just switch our build farm to lzip overnight; we needed to devise a transition strategy.

Guix asks for the availability of substitutes over HTTP. For example, a question such as:

“Dear server, do you happen to have a binary of /gnu/store/6yc4ngrsig781bpayax2cg6pncyhkjpq-emacs-26.2 that I could download?”

translates into prose to an HTTP GET of https://ci.guix.gnu.org/6yc4ngrsig781bpayax2cg6pncyhkjpq.narinfo, which returns something like:

StorePath: /gnu/store/6yc4ngrsig781bpayax2cg6pncyhkjpq-emacs-26.2 URL: nar/gzip/6yc4ngrsig781bpayax2cg6pncyhkjpq-emacs-26.2 Compression: gzip NarHash: sha256:0h2ibqpqyi3z0h16pf7ii6l4v7i2wmvbrxj4ilig0v9m469f6pm9 NarSize: 134407424 References: 2dk55i5wdhcbh2z8hhn3r55x4873iyp1-libxext-1.3.3 … FileSize: 48501141 System: x86_64-linux Deriver: 6xqibvc4v8cfppa28pgxh0acw9j8xzhz-emacs-26.2.drv Signature: 1;berlin.guixsd.org;KHNpZ25hdHV…

(This narinfo format is inherited from Nix and implemented here and here.) This tells us we can download the actual binary from /nar/gzip/…-emacs-26.2, and that it will be about 46 MiB (the FileSize field.) This is what guix publish serves.

The trick we came up with was to allow guix publish to advertise several URLs, one per compression format. Thus, for recently-built substitutes, we get something like this:

StorePath: /gnu/store/mvhaar2iflscidl0a66x5009r44fss15-gimp-2.10.12 URL: nar/gzip/mvhaar2iflscidl0a66x5009r44fss15-gimp-2.10.12 Compression: gzip FileSize: 30872887 URL: nar/lzip/mvhaar2iflscidl0a66x5009r44fss15-gimp-2.10.12 Compression: lzip FileSize: 18829088 NarHash: sha256:10n3nv3clxr00c9cnpv6x7y2c66034y45c788syjl8m6ga0hbkwy NarSize: 94372664 References: 05zlxc7ckwflz56i6hmlngr86pmccam2-pcre-8.42 … System: x86_64-linux Deriver: vi2jkpm9fd043hm0839ibbb42qrv5xyr-gimp-2.10.12.drv Signature: 1;berlin.guixsd.org;KHNpZ25hdHV…

Notice that there are two occurrences of the URL, Compression, and FileSize fields: one for gzip, and one for lzip. Old Guix instances will just pick the first one, gzip; newer Guix will pick whichever supported method provides the smallest FileSize, usually lzip. This will make migration trivial in the future, should we add support for other compression methods.

Users need to upgrade their Guix daemon to benefit from lzip. On a “foreign distro”, simply run guix pull as root. On standalone Guix systems, run guix pull && sudo guix system reconfigure /etc/config.scm. In both cases, the daemon has to be restarted, be it with systemctl restart guix-daemon.service or with herd restart guix-daemon.

First impressions

This new gzip+lzip scheme has been deployed on ci.guix.gnu.org for a week. Specifically, we run guix publish -C gzip:9 -C lzip:9, meaning that we use the highest compression ratio for both compression methods.

Currently, only a small subset of the package substitutes are available as both lzip and gzip; those that were already available as gzip have not been recompressed. The following Guile program that taps into the API of guix weather allows us to get some insight:

(use-modules (gnu) (guix) (guix monads) (guix scripts substitute) (srfi srfi-1) (ice-9 match)) (define all-packages (@@ (guix scripts weather) all-packages)) (define package-outputs (@@ (guix scripts weather) package-outputs)) (define (fetch-lzip-narinfos) (mlet %store-monad ((items (package-outputs (all-packages)))) (return (filter (lambda (narinfo) (member "lzip" (narinfo-compressions narinfo))) (lookup-narinfos "https://ci.guix.gnu.org" items))))) (define (lzip/gzip-ratio narinfo) (match (narinfo-file-sizes narinfo) ((gzip lzip) (/ lzip gzip)))) (define (average lst) (/ (reduce + 0 lst) (length lst) 1.))

Let’s explore this at the REPL:

scheme@(guile-user)> (define lst (with-store s (run-with-store s (fetch-lzip-narinfos)))) computing 9,897 package derivations for x86_64-linux... updating substitutes from 'https://ci.guix.gnu.org'... 100.0% scheme@(guile-user)> (length lst) $4 = 2275 scheme@(guile-user)> (average (map lzip/gzip-ratio lst)) $5 = 0.7398994395478715

As of this writing, around 20% of the package substitutes are available as lzip, so take the following stats with a grain of salt. Among those, the lzip-compressed substitute is on average 26% smaller than the gzip-compressed one. What if we consider only packages bigger than 5 MiB uncompressed?

scheme@(guile-user)> (define biggest (filter (lambda (narinfo) (> (narinfo-size narinfo) (* 5 (expt 2 20)))) lst)) scheme@(guile-user)> (average (map lzip/gzip-ratio biggest)) $6 = 0.5974238562384483 scheme@(guile-user)> (length biggest) $7 = 440

For those packages, lzip yields substitutes that are 40% smaller on average. Pretty nice! Lzip decompression is slightly more CPU-intensive than gzip decompression, but downloads are bandwidth-bound, so the benefits clearly outweigh the costs.

Going forward

The switch from gzip to lzip has the potential to make upgrades “feel” faster, and that is great in itself.

Fundamentally though, we’ve always been looking in this project at peer-to-peer solutions with envy. Of course, the main motivation is to have a community-supported and resilient infrastructure, rather than a centralized one, and that vision goes hand-in-hand with reproducible builds.

We started working on an extension to publish and fetch substitutes over IPFS. Thanks to its content-addressed nature, IPFS has the potential to further reduce the amount of data that needs to be downloaded on an upgrade.

The good news is that IPFS developers are also interested in working with package manager developers, and I bet there’ll be interesting discussions at IPFS Camp in just a few days. We’re eager to pursue our IPFS integration work, and if you’d like to join us and hack the good hack, let’s get in touch!

About GNU Guix

GNU Guix is a transactional package manager and an advanced distribution of the GNU system that respects user freedom. Guix can be used on top of any system running the kernel Linux, or it can be used as a standalone operating system distribution for i686, x86_64, ARMv7, and AArch64 machines.

In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. When used as a standalone GNU/Linux distribution, Guix offers a declarative, stateless approach to operating system configuration management. Guix is highly customizable and hackable through Guile programming interfaces and extensions to the Scheme language.

Categories: FLOSS Project Planets

Stack Abuse: Introduction to OpenCV with Python

Planet Python - Mon, 2019-06-17 08:26

In this tutorial, we are going to learn how to use OpenCV library in Python. OpenCV is an open source library which is supported by multiple platforms including Windows, Linux, and MacOS, and is available for use in multiple other languages as well; however, it is most commonly used in Python for Machine Learning applications, specifically in the Computer Vision domain.

Apart from its cross-platform support and availability in multiple other computer languages, which allows applications developed in it to be used on different systems, OpenCV is also, in comparison to other such libraries, fairly efficient in terms of computations, as it uses vector operations for most of its functions.

In this tutorial, we'll cover OpenCV installation on Mac, Windows, and Linux, image operations, image arithmetics, image smoothing, and geometric transformations using OpenCV. So without further ado, let's start.


Note: Since we are going to use OpenCV in the Python language, it is an implicit requirement that you already have Python (version 3) installed on your workstation. Depending upon your OS, execute one of the following commands to install OpenCV library on your system:


$ pip install opencv-python


$ brew install opencv3 --with-contrib --with-python3


$ sudo apt-get install libopencv-dev python-opencv

To check if your installation was successful or not, run the following command in either a Python shell, or your command prompt/ terminal:

import cv2

If you do not get an error on importing cv2 then it was installed correctly.

Basic Image Operations

Now that we have installed OpenCV on our workstations, let's get our hands dirty with some of the functionalities that OpenCV offers.

Display an Image

Displaying an image using OpenCV is a two-step process; first, we have to load it, and then we can display it. Both operations are done in sequence using different functions.

To display an image, we need to know two things:

  1. Image Path (both absolute and relative paths work)
  2. Read Mode (read, write, etc.)

The function we'll use for reading/loading an image is cv2.imread(), which has two variations. First one is IMREAD_GRAYSCALE, which as the name suggests, converts the image to grayscale before reading it. The second one is IMREAD_UNCHANGED, which loads the image without cutting out the alpha channel. The default is IMREAD_COLOR, which simply reads the colored image using the RGB channels only.

Let's code an example:

import cv2 my_bike = cv2.imread('bike.png')

This will load the image of a bike from the file system and store it in the my_bike variable for further operations

Note: If you get an error from the above code, there are only three possible reasons for it. The first one is that the path you specified is incorrect, second is that the image file you specified doesn't exist, and the last one is that the image type (jpg/jpeg/png) in the image path is incorrect.

Let's now display the image we just read. It can be done by the cv2.imshow() function. If you have used Matlab, you may be familiar with these image operations.

cv2.imshow('my_bike', my_bike)

The first parameter to the imshow() function is the string name that you want to display on the image window. The second parameter is the image handler we created using the cv2.imread() function.

Saving an Image

Saving an image is a very commonly used feature, as we may need to update our image and save the changes to the file system for later use. OpenCV has an cv2.imwrite() function to save images.

Here is an example:

cv2.imwrite('bike.png', my_bike)

Here we specify the name and current location of the image. The resulting image is automatically saved in the current working directory.

Arithmetic Operations on Images

Arithmetic operations on images refer to adding, subtracting, multiplying, or dividing multiple images to generate a new image which is an arithmetic combination of the input images. Image arithmetics has a lot of applications, like adding a watermark to an image, creating a blended combination of two images, applying different types of image filters, etc.

While there are many operations you can perform, we will only be showing two examples here, as this will then allow you to apply the concept to other arithmetic operations available in OpenCV. The first example will be the addition of two images, and the second example will be blending two images.

Let's code these two examples:

Adding Images import cv2 # Read in the two images image_1 = cv2.imread('bike.jpg') image_2 = cv2.imread('car.jpg') # Sum the two image arrays for all channels result = cv2.add(image_1, image_2) cv2.imshow('result', result) cv2.waitKey(0) cv2.destroyAllWindows()

The waitKey command will wait for you to press a key before it moves on to the next command. This is useful so that the program will continue to display your image until a key is pressed, otherwise it will be displayed for a split second and then quickly disappear once the program has stopped executing.

Blending Images

Blending images is similar to image addition, except each image's contribution to the new resulting image can be controlled. Basically, if we want one image to be more focused, and the other one to be more faint when they get merged, we will go with blending, instead of simple addition.

Lets code it to clarify further:

import cv2 # Read in the two images image_1 = cv2.imread('bike.jpg') image_2 = cv2.imread('car.jpg') result = cv2.addWeighted(image_1, 0.9, image_2, 0.1) cv2.imshow('result', result) cv2.waitKey(0) # Wait for the user to press a key before continuing cv2.destroyAllWindows()

The sum of the weights given to the addWeighted function should be equal to 1.0. You can also give a scalar value at the end, which would be added to all the pixel values of the resultant image.

Note: The images can be of any type; however, the type should be the same for all images. For instance, if you are using PNG format, all images being used for computation should be in PNG format as well.

Image Smoothing

Image smoothing is a very helpful feature, which is mostly performed before the images are passed on to a machine learning model. It is mostly done to remove noise/high-frequency elements from images by passing the image through a low-pass filter. There are many filters, including box filter (averaging filter), median filter, mode filter, Gaussian filter, and many more; however, to understand image smoothing and how to do it using OpenCV, we will only cover the box filter.

Let's say you have an image of 10x10, and you want to pass it through a 3x3 box/averaging filter, how would you do it?

You'll start with the top left of the image, place your 3x3 filter there, and replace the central element with the average of all 9 elements. This was the first step, now you will move your filter one step to the right, and repeat the same process until you have covered the whole image. An example of 10x10 image, and 3x3 averaging filter are shown below for your reference:


Filter being applied on 10x10 Image:

Now that we have discussed how it works, lets try and see how we can apply different filters on our image using OpenCV; please read the comments thoroughly to know which line of code is used for which filter:

import cv2 # Load the original image original_image = cv2.imread('my_bike.png') # Filter by passing image through 3x3 averaging filter average_image = cv2.blur(original_image,(3,3)) # Apply 3x3 gaussian filter on the original image gaussian_image = cv2.GaussianBlur((original_image,(3,3),0)) # Apply 3x3 median filter on the original image median_image = cv2.medianBlur(original_image,3)

Note: You can view the resulting images by using the following additional code:

import matplotlib.pyplot as plt plt.imshow(average_image) plt.show() Image Transformations

Image transformation is the last, but one of the most important topics that we are going to cover with OpenCV. It has a lot of applications, but one of the most common ones nowadays is in Machine Learning for Data Augmentation, i.e. when you have a shortage of dataset, you augment/transform the currently available images to make them different from your existing dataset. This effectively increases your dataset size and might help in improving your model accuracy.

The list of possible transformations is a long one, including scaling, affine, rotation, translation, etc. We will only cover two of them using OpenCV to get a general idea; however, OpenCV provides supporting functions for a wide range of them. Let's start with scaling.


To put it in simple words, scaling is basically just resizing your image, i.e. either making it bigger or smaller. resize is the function used for scaling the images in OpenCV. Resizing has three types: INTER_CUBIC, INTER_LINEAR, and INTER_AREA. Let's code an example using these functions for scaling; please read through the code, comments, and descriptions carefully as they will explain what exactly is going on in the code:

import cv2 import numpy as np import matplotlib.pyplot as plt image = cv2.imread('my_bike.jpg') # Scale up/expand both width and height by factor of 2 result_1 = cv2.resize(image, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) # Scale down/shrink both width and height by factor of 2 result_2 = cv2.resize(image, None, fx=2, fy=2, interpolation=cv2.INTER_AREA) # Display the resulting images plt.imshow(result_1) plt.imshow(result_2) plt.show()

Here in the resize function, the fx parameter in represents the scale factor for width, fy represents the scale factor height, and interpolation specifies the function to be used for scaling (shrinking or expansion).


Rotation allows us to move an image about the axis for a certain specified angle.

Before we learn how to rotate our images using code, we should know that there is a rotation matrix that is used for performing this transformation; we will not go in details of that, as OpenCV makes it very simple for us to calculate that matrix using a single function call. You will see that in the code below:

import cv2 import matplotlib.pyplot as plt # Load the image of a bike image = cv2.imread('my_bike.jpg',0) # Rows and columns r, c = image.shape matrix = cv2.getRotationMatrix2D((cols/2,rows/2), 180, 1) result = cv2.warpAffine(image,matrix,(c,r)) # Display resulting rotation plt.imshow(result) plt.show()

In the getRotationMatrix2D function, 180 specifies the degree by which the image should be rotated, 1 is the scaling factor, the function call would return the rotation matrix in the matrix variable.

The warpAffine function call uses the matrix we calculated from the previous method to rotate the image according to our specifications.


To conclude it all, let's reiterate over some important points that we discussed in this article. OpenCV is a library available in multiple languages and is mostly used in conjunction with NumPy, SciPy and Matplotlib, as we saw in some of the examples above, as well. Some of its functions are the same as in Matlab, and it also supports vectorized operations, hence increasing computational efficiency.

Furthermore, OpenCV is one of the best libraries out there for the Computer Vision domain, and after reading this article, you should be able to go ahead and search up some computer vision / machine learning applications that have been developed using OpenCV.

Let it be known that this article was just the tip of the iceberg, and OpenCV has a lot more to offer. Reading this should enable you to dive deeper and learn about other advanced features that OpenCV has to offer.

Categories: FLOSS Project Planets

Reuven Lerner: Reminder: Early-bird pricing for Weekly Python Exercise ends tomorrow

Planet Python - Mon, 2019-06-17 08:01

This is just a quick reminder that if you want to join the advanced cohort of Weekly Python Exercise starting July 2nd, you should do it by tomorrow (Tuesday, June 18th).

Don’t miss this opportunity to improve your Python coding skills! We’ll be talking about iterators, generators, decorators, threads, and functional programming, and helping you to improve your skills.

Questions? Just e-mail me at reuven@lerner.co.il. But hurry, before the price goes up!

The post Reminder: Early-bird pricing for Weekly Python Exercise ends tomorrow appeared first on Reuven Lerner.

Categories: FLOSS Project Planets

Catalin George Festila: Python Qt5 - the most simple QTreeWidget - part 002.

Planet Python - Mon, 2019-06-17 07:41
This tutorial uses PyQt5 and Python version 3.7.3. Let's install the PyQt5 python module with the pip tool: C:\Python373\Scripts>pip install PyQt5 Collecting PyQt5 ... Successfully installed PyQt5-5.12.2 PyQt5-sip-4.19.17Let's see one simple example with comments about how to use QTreeWidget. import sys from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QApplication, QWidget if __name__ =
Categories: FLOSS Project Planets