Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

"Hey! Is That My Car? How to Sharpen a QuickBird Satellite Image Using DotImage"

Atalasoft leverages their DotImage toolkit to manipulate color channels for the purpose of image enhancement, in this case satellite images. The article is a tutorial on image enhancement and it includes all source code and test images.

Editorial Note

This article is in the Product Showcase section for our sponsors at CodeProject. These reviews are intended to provide you with information on products and services that we consider useful and of value to developers.

channelexplorer.zip
ChannelExplorer
atalasoft-color.jpg
atalasoft-gray.jpg
bin
Release
Atalasoft.DotAnnotate.dll
Atalasoft.dotImage.dll
Atalasoft.dotImage.Lib.dll
Atalasoft.dotImage.WinControls.dll
Atalasoft.Shared.dll
ChannelExplorer.exe
ChannelExplorer.vshost.exe
Images
Properties
licenses.licx
Settings.settings
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Atalasoft.Imaging;
using Atalasoft.Imaging.Codec;
using Atalasoft.Imaging.ImageProcessing;
using Atalasoft.Imaging.ImageProcessing.Channels;

namespace ChannelExplorer
{
    public partial class frmChannelExplorer : Form
    {

        private AtalaImage _originalImage;

        public frmChannelExplorer()
        {
            InitializeComponent();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            try
            {
                if (GetMainColorImageFromUser())
                {
                    ResetChannelImages();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error opening image", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnReload_Click(object sender, EventArgs e)
        {
            if (_originalImage != null)
            {
                imgColor.Image = _originalImage;
                ResetChannelImages();
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Joint Photographic Experts Group (*.jpg)|*.jpg";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                imgColor.Image.Save(sfd.FileName, new JpegEncoder(), null);
            }
        }

        private void ResetChannelImages()
        {
            if (imgColor.Image == null)
            {
                return;
            }
            if (radioChannelBGR.Checked)
            {
                SetChannelsFromImage(imgColor.Image);
            }
            else
            {
                AtalaImage hslImage = (AtalaImage)(imgColor.Image.Clone());
                hslImage = ConvertHSL(hslImage, true);
                SetChannelsFromImage(hslImage);
            }
        }

        private void SetChannelsFromImage(AtalaImage img)
        {
            AtalaImage[] channels = img.SplitChannels();
            if (channels.Length > 0)
            {
                imgChannel1.Image = channels[0];
                if (channels.Length > 1)
                {
                    imgChannel2.Image = channels[1];
                    if (channels.Length > 2)
                    {
                        imgChannel3.Image = channels[2];
                    }
                }
            }
        }

        private AtalaImage GetImageFromUser()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = CreateDialogFilter();
            ofd.Title = "Select an image file";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                return new AtalaImage(ofd.FileName);
            }
            return null;
        }

        private bool GetMainColorImageFromUser()
        {
            AtalaImage img = GetImageFromUser();
            if (img != null)
            {
                _originalImage = img;
                imgColor.Image = _originalImage;
                EnableButtons(true);
                return true;
            }
            return false;
        }

        private void EnableButtons(bool enable)
        {
            btnReload.Enabled = enable;
            btnSave.Enabled = enable;
            btnSubChannel1.Enabled = enable;
            btnSubChannel2.Enabled = enable;
            btnSubChannel3.Enabled = enable;
        }

        public string CreateDialogFilter()
        {
            string filter = "All Supported Images|*.jpg;*.png;*.tif;*.tiff;*.pcx;*.tga;*.bmp;*.wmf;*.emf;*.psd;*.wbmp;*.gif;*.tla;*.pcd";
            filter += "|Joint Photographic Experts Group (*.jpg)|*.jpg";
            filter += "|Portable Network Graphic (*.png)|*.png";
            filter += "|Tagged Image File (*.tif, *.tiff)|*.tif;*.tiff";
            filter += "|ZSoft PaintBrush (*.pcx)|*.pcx";
            filter += "|Truevision Targa (*.tga)|*.tga";
            filter += "|Windows Bitmap (*.bmp)|*.bmp";
            filter += "|Windows Meta File (*.wmf)|*.wmf";
            filter += "|Enhanced Windows Meta File (*.emf)|*.emf";
            filter += "|Adobe (tm) Photoshop format (*.psd)|*.psd";
            filter += "|Wireless Bitmap (*.wbmp)|*.wbmp";
            filter += "|Graphics Interchange Format (*.gif)|*.gif";
            filter += "|Smaller Animals TLA (*.tla)|*.tla";
            filter += "|Kodak (tm) PhotoCD (*.pcd)|*.pcd";
            return filter;
        }

        private void radioChannelRGB_CheckedChanged(object sender, EventArgs e)
        {
            ResetChannelImages();
        }

        private void radioChannelHSL_CheckedChanged(object sender, EventArgs e)
        {
            ResetChannelImages();
        }

        private void btnSubChannel1_Click(object sender, EventArgs e)
        {
            SubstituteChannel(0);
        }

        private void btnSubChannel2_Click(object sender, EventArgs e)
        {
            SubstituteChannel(1);
        }

        private void btnSubChannel3_Click(object sender, EventArgs e)
        {
            SubstituteChannel(2);
        }

        private void SubstituteChannel(int channelNum)
        {
            try {
                AtalaImage grayImg = GetGrayscaleImageFromUser();
                if (grayImg == null)
                {
                    return;
                }                

                AtalaImage newColorImage = (AtalaImage)(imgColor.Image.Clone());

                // resize the image to the new channel image's size
                newColorImage = ResizeImageToSize(newColorImage, grayImg.Size);

                // do the channel substitution
                newColorImage = ReplaceChannelUsingSettings(newColorImage, grayImg, channelNum);

                // use the newColorImage
                SetMainImage(newColorImage);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error substituting channel", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SetMainImage(AtalaImage newColorImage)
        {
            AtalaImage oldImg = imgColor.Image;
            imgColor.Image = newColorImage;
            if (oldImg != _originalImage)
            {
                oldImg.Dispose();
            }

            // update the channel images
            ResetChannelImages();
        }

        private AtalaImage GetGrayscaleImageFromUser()
        {
            AtalaImage img = GetImageFromUser();
            if (img == null)
            {
                return null;
            }
            if (img.PixelFormat != PixelFormat.Pixel8bppGrayscale)
            {
                MessageBox.Show("Channel image must be a grayscale image", "Image is wrong format", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
            return img;
        }

        private AtalaImage ReplaceChannelUsingSettings(AtalaImage newColorImage, AtalaImage img, int channelNum)
        {
            if (radioChannelBGR.Checked)
            {
                // replace the channel with the gray image
                newColorImage = ReplaceChannel(newColorImage, img, channelNum);
            }
            else 
            {
                // HSL channel substitution
                newColorImage = ConvertHSL(newColorImage, true);
                newColorImage = ReplaceChannel(newColorImage, img, channelNum);
                newColorImage = ConvertHSL(newColorImage, false);
            }
            return newColorImage;
        }

        private AtalaImage ConvertHSL(AtalaImage img, bool toHsl)
        {
            HslConvertCommand cmd = new HslConvertCommand(toHsl);
            return cmd.Apply(img).Image;            
        }

        private AtalaImage ReplaceChannel(AtalaImage img, AtalaImage channelImage, int channelNum)
        {
            AtalaImage[] imgs = {null, null, null, null};
            imgs[channelNum] = channelImage;                    

            ReplaceChannelCommand cmd = new ReplaceChannelCommand(imgs);
            ImageResults res = cmd.Apply(img);
            if (!res.IsImageSourceImage)
            {
                img.Dispose();
                img = res.Image;
            }
            return img;
        }

        private AtalaImage ResizeImageToSize(AtalaImage img, Size size)
        {
            // make sure the image is the right size
            if (img.Size != size)
            {
                ResampleCommand cmd = new ResampleCommand(size);
                ImageResults res = cmd.Apply(img);
                if (!res.IsImageSourceImage)
                {
                    img.Dispose();
                    img = res.Image;
                }
            }
            return img;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Lou Franco
Atalasoft, Inc.
United States United States
Lou Franco is the Director of Engineering at Atalasoft, provider of the leading .NET Imaging SDK (DotImage) and the Document Viewer for SharePoint (Vizit).
 
http://atalasoft.com/products/dotimage
http://vizitsp.com

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 13 Nov 2007
Article Copyright 2007 by Lou Franco
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid