Image for post
Image for post

Median filtering can be used to join multiple images to get a single image with all moving objects removed. The simple idea is to compare the pixels at the same location on all images and get the median of RGBA values of the pixels to form a new composite image with all moving objects removed.

The image set provided has to be taken by a camera that did not move during the shoot, since the pixels at the same location on all images have to correspond to the same physical location. Otherwise, the median filter will blend all images together to create a meaningless composite image. …

Image for post
Image for post

Part 1 — Utility Functions

I have been interested in image manipulation for some time. Last year I worked on a small package that does simple image manipulation using Go’s standard image package:

Let’s look at how to read an image from a provided file path and creating an image object. This is what the structs will look like.

// GrayscaleAverage, GrayscaleLuma, GrayscaleDesaturation
// are used by grayscale to choose between algorithms
const (
GrayscaleAverage = 0
GrayscaleLuma = 1
GrayscaleDesaturation = 2

// Pixel is a single pixel in 2d array
type Pixel struct {
R int
G int
B int
A int

// Image is the main object that holds information about the
// image file. …

Image for post
Image for post

The default HTTP client in Go uses the default DNS resolver available on the machine. There are some cases where you might want to use a different DNS resolver.

I want to quickly show how you can change the DNS resolver for the default HTTP client. We are using this same method for our custom DNS resolver in my company: Violetnorth

// Changing DNS resolverpackage main

import (

func main() {
var (
dnsResolverIP = "" // Google DNS resolver.
dnsResolverProto = "udp" // Protocol to use for the DNS resolver
dnsResolverTimeoutMs = 5000 // Timeout (ms) for the DNS resolver (optional)

dialer := &net.Dialer{
Resolver: &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Duration(dnsResolverTimeoutMs) * time.Millisecond,
return d.DialContext(ctx, dnsResolverProto, dnsResolverIP)

dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, addr)

http.DefaultTransport.(*http.Transport).DialContext …


Koray Göçmen

University of Toronto, Computer Engineering, architected and implemented reliable infrastructures and worked as the lead developer for multiple startups.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store