Classes and such

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

30 Replies - 4162 Views - Last Post: 22 September 2014 - 11:03 PM Rate Topic: -----

#1 wartimespark   User is offline

  • D.I.C Head


Reputation: -4
  • View blog
  • Posts: 82
  • Joined: 05-September 14

Classes and such

Posted 17 September 2014 - 04:33 PM

I'm having a problem in my program where most of its operations appears to be in one buttonstart_Click class. It appears I am not using C# to its full potential but when I try to separate logic into different classes nothing compiles because my variables are out of scope.

I have visited tutorials for C# but they use examples like Dog Breed and Car Engines and it doesn't make sense in the context of real programming.

For example, I am working on an OCR program. It seems I should be able to do OCR image processing prep in a class of its own, then use another class to do OCR and output to string, then use another class to do any necessary parsing, etc. Am I understanding the role of classes right?

Is This A Good Question/Topic? 0
  • +

Replies To: Classes and such

#2 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Classes and such

Posted 17 September 2014 - 06:50 PM

Quote

I have visited tutorials for C# but they use examples like Dog Breed and Car Engines and it doesn't make sense in the context of real programming.


How are car engines and animals not 'real' programming? I'm sure the people at the vets office consider their needs to be real. And with hundreds of millions of dollars in revenue, the auto industry which uses robots to build the cars would be considered 'real' programming.

Forgive the brutally blunt remark here but...
If you're not following the simple examples of classes where every day objects that you are familiar with are used... I don't see how you're suddenly going to grasp the concepts for MORE COMPLEX structures.

As I am most familiar with my own tutorials please do me a favor... Work through my tutorial on classes and objects (its linked in my signature block) and let me know what you find confusing. If there are areas I can improve the tutorial so it helps more people I would like to do that.

To answer your question about *can* you use classes for OCR the way you've described... Yes you can. But what you've described is so vague its hard to say if its the *best* way. I mean you *can* with enough money time and parts turn a VW beatle into a Mac truck. But just because you can do a thing doesn't mean you should. You would be just as right to say you are going to make one class to handle your OCR needs, with methods that do the pre-processing, actual OCR, and etc. Its pretty much up to your needs, direction and design as to how you want to go.
Was This Post Helpful? 3
  • +
  • -

#3 wartimespark   User is offline

  • D.I.C Head


Reputation: -4
  • View blog
  • Posts: 82
  • Joined: 05-September 14

Re: Classes and such

Posted 17 September 2014 - 07:01 PM

Thanks, I have to admit my post was a little sarcastic and frustrated. Your tutorial seems down to earth and plain English. I'll go through it tomorrow morning. I think it will help me a lot. I mean I have a book about C# but its very dense and I want to learn faster than that haha.

Thanks again I'll let you know how it works out for me.
Was This Post Helpful? 0
  • +
  • -

#4 Charles:)   User is offline

  • D.I.C Regular

Reputation: 149
  • View blog
  • Posts: 359
  • Joined: 26-November 09

Re: Classes and such

Posted 18 September 2014 - 09:31 AM

An extremely simplified version of an OCR class might look something like this
class OcrProcessor
{
	public string DetectText(Image image)
	{
		// Do work here and return the text found in the image.
	}
}


Your click handler could then look like this:
private void HandleButtonclick(object sender, EventArgs args)
{
	var ocr = new OcrProcessor();
	
	var text = ocr.DetectText(myImage);
	
	MessageBox.Show(text);
}

Again, this is a very simplified view, but it should give you an idea of the way that you want to separate your logic from your GUI. Notice that all of the work is done in the OcrProcessor class, and the GUI simply uses that class rather than doing any OCR processing of its own.

Apart from keeping your GUI clean, this has the advantage that it's easy to provide other GUIs, e.g. you could use the same OcrProcessor class from a console application or from a website. You can also write unit tests for the OcrProcessor class. In contrast, it's much harder to unit test a GUI.

This post has been edited by Charles:): 18 September 2014 - 09:33 AM

Was This Post Helpful? 1
  • +
  • -

#5 wartimespark   User is offline

  • D.I.C Head


Reputation: -4
  • View blog
  • Posts: 82
  • Joined: 05-September 14

Re: Classes and such

Posted 18 September 2014 - 11:19 AM

Hi thanks for your reply..

I want to rewrite all code I have to learn proper formatting, make the code easier for me to understand and for others to understand as well.

I rewrote a small part of my code which handles capturing an image from the webcam using your example as a reference..

Here is my worker class "CamFeed"
class CamFeed
    {
        private Capture cam = null;
        public Image<Bgr, Byte> GetFrame()
        {
            cam = new Capture();
            Image<Bgr, Byte> frame = cam.RetrieveBgrFrame();
            return frame;
        }
    }

Here is the button click which calls it up and puts it in the GUI..
public partial class OCRCleanup : Form
    {
        private void buttonstart_Click(object sender, EventArgs e)
        {
            Image<Bgr, Byte> cam = new CamFeed();
        }        
    }

There is an error on line 5 of buttonstart_Click which says "Cannot implicitly convert type 'CamFeed' to 'Image<Bgr,Byte>'. The variable I return in CamFeed is absolutely of the same type Image<Bgr, Byte>... is it really "sending over" the right information?
Was This Post Helpful? 0
  • +
  • -

#6 wartimespark   User is offline

  • D.I.C Head


Reputation: -4
  • View blog
  • Posts: 82
  • Joined: 05-September 14

Re: Classes and such

Posted 18 September 2014 - 11:28 AM

I should rename "cam" to "image" in the buttonstart_Click, and also there is some more operations to do before this code would work in practice but I'm trying to get over the syntax hump now.
Was This Post Helpful? 0
  • +
  • -

#7 andrewsw   User is online

  • dependency injected
  • member icon

Reputation: 6668
  • View blog
  • Posts: 27,308
  • Joined: 12-December 12

Re: Classes and such

Posted 18 September 2014 - 11:33 AM

Quote

The variable I return in CamFeed is absolutely of the same type Image<Bgr, Byte>

No it isn't. new CamFeed() is constructing an instance of CamFeed. It is using the default constuctor. Constructors obtain an instance of the class which, in this case, is a CamFeed instance. You cannot work with "Classes and stuff" until you understand constructors (and many other things).

You have a method named GetFrame() which returns an Image<Bgr, Byte>.

View Postwartimespark, on 18 September 2014 - 06:28 PM, said:

I should rename "cam" to "image" in the buttonstart_Click, and also there is some more operations to do before this code would work in practice but I'm trying to get over the syntax hump now.

Renaming "cam" to "image" will make no difference. You need to study OOP, classes, objects, constructors. Fumbling around won't get you anywhere.
Was This Post Helpful? 2
  • +
  • -

#8 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Classes and such

Posted 18 September 2014 - 11:37 AM

Quote

I mean I have a book about C# but its very dense and I want to learn faster than that haha.


  • What book do you have?
  • How far have you worked through it?
  • *ARE* you working your way through it from start to finish, or are you using it like a reference book and only looking stuff up when you get lost like it was a dictionary?

Was This Post Helpful? 1
  • +
  • -

#9 andrewsw   User is online

  • dependency injected
  • member icon

Reputation: 6668
  • View blog
  • Posts: 27,308
  • Joined: 12-December 12

Re: Classes and such

Posted 18 September 2014 - 11:41 AM

tlhIn`toq said:

a reference book and only looking stuff up when you get lost like it was a dictionary?

Yes, a dictionary is of no use to someone without a basic vocabulary.

This post has been edited by andrewsw: 18 September 2014 - 11:43 AM

Was This Post Helpful? 1
  • +
  • -

#10 Curtis Rutland   User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 5104
  • View blog
  • Posts: 9,283
  • Joined: 08-June 10

Re: Classes and such

Posted 18 September 2014 - 11:47 AM

It's because you're not calling it correctly. CamFeed is a class. When you call new CamFeed() it returns a new object of type CamFeed. The type of object you want to handle is Image<Bgr, Byte>. CamFeed isn't an Image<Bgr, Byte>. But a method on the CamFeed class does return an Image<Bgr, Byte>.

So if you want that value, you have to call the method on the instance of the CamFeed class you've created. Something like this:

CamFeed feed = new CamFeed();
Image<Bgr, Byte> image = feed.GetFrame();


However, at this point, there's no reason for your CamFeed class. It's not gaining you anything; it's not saving you effort. Because you could just as easily do this:

Capture cam = new Capture();
Image<Bgr, Byte> image = cam.RetrieveBgrFrame();


See how you haven't really gained anything? You've just wrapped one class with another, adding a layer of complexity without gaining any benefit.

Notice how in Charles:)'s example, he has a class that has a method that returns a string. The way you'd "fill that in" would be to do all the work needed to capture and parse the text and return that, not the objects required to get the text.

You want to encapsulate functionality, not just wrap one class with another.
Was This Post Helpful? 2
  • +
  • -

#11 wartimespark   User is offline

  • D.I.C Head


Reputation: -4
  • View blog
  • Posts: 82
  • Joined: 05-September 14

Re: Classes and such

Posted 18 September 2014 - 01:56 PM

Hi thank you for replies. I'm sure they will help get me on track.

Quote

However, at this point, there's no reason for your CamFeed class. It's not gaining you anything; it's not saving you effort.


That's how I felt when I was putting my original code together... but then after a few days I ended up with everything in a "public partial class Form1 : Form." There was almost no organization, just methods inside one huge class.

Following this logic I don't actually need the OCR class because if put this at the beginning of my only class...
private Tesseract ocr;
and this inside my do-everything Click method...
ocr.Recognize(myImage);
String text = ocr.GetText();

then that works just fine right?

And since my camera function is also in the click method, I might as well do image processing in the click method.

I guess my question is what constitutes "functionality". It seems like RetrieveBgrFrame(); is "functionality". What if later I want another method to have access to an unadulterated frame. It would be easier to create a new "object" (clean frame) from the "blueprint" (frame grabber) and do logic in a new class. The alternative is making my buttonstart method even bigger and more unreadable.

Quote

You cannot work with "Classes and stuff" until you understand constructors (and many other things).


But it's true I need more knowledge on how C# works. This is me learning... I read my book about "Constructors" and all I gathered was that constructors allow you to provide some "run once" operations to your classes once they are instantiated, but I do not know that I need this functionality right now. The default constructor which, as I understand it, initializes all variables and zeros them out is fine. I suppose my bit right before the first method "private Capture cam = null;" was redundant, but then again the code will not compile if I take it away.

This post has been edited by wartimespark: 18 September 2014 - 02:10 PM

Was This Post Helpful? 0
  • +
  • -

#12 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Classes and such

Posted 18 September 2014 - 02:07 PM

Quote

And since my camera function is also in the click method, I might as well do image processing in the click method.


No no no. I know I said before to NOT put everything in the GUI handler methods. That's just bad practice.

You want all the OCR code in its own class. But just one class for handling the OCR stuff should be fine.

The reason for this is separation of responsibilities. Also, so you can migrate and upgrade the solution without having to duplicate all your code. What if you want to move this from WinForms to WPF? What if you want to make a solution that does the OCR without any GUI, but just works automatically as you import 1,000 photos from your camera?

If the OCR stuff is separate you can think of it as a reusable library. Don't bury it in your Form/window. Instead you can access it FROM your window. That way you can use it in this project, and the next 100 solutions you make without having to copy/paste it every time. Also, when you update the OCR library class all you have to do is recompile your other projects and they will have the updated code. (not getting into DLL's right now)
Was This Post Helpful? 1
  • +
  • -

#13 wartimespark   User is offline

  • D.I.C Head


Reputation: -4
  • View blog
  • Posts: 82
  • Joined: 05-September 14

Re: Classes and such

Posted 18 September 2014 - 02:12 PM

View PosttlhIn`toq, on 18 September 2014 - 02:07 PM, said:

No no no. I know I said before to NOT put everything in the GUI handler methods. That's just bad practice.

I agree. I am currently working to wrap my mind around how I can separate all the pieces and responsibilities into the smallest classes and/or methods as possible.
Was This Post Helpful? 0
  • +
  • -

#14 wartimespark   User is offline

  • D.I.C Head


Reputation: -4
  • View blog
  • Posts: 82
  • Joined: 05-September 14

Re: Classes and such

Posted 18 September 2014 - 02:18 PM

One issue I am having as I shift this code around to see how it behaves:
private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (cam != null)
            {
                if (captureInProgress == true)
                {
                    cam.Pause();
                    buttonstart.Content = "Start";
                }
                else
                {
                    cam.Start();
                    buttonstart.Content = "Pause";
                }
            }
            captureInProgress = !captureInProgress;
        }

I like this functionality and I understand how it works. But, when I place it in a class other than MainWindow : Window (you can see I moved to WPF) I get the error "The name 'cam' does not exist in the current context". When I move it to the class where 'cam' does exist, I get the error "The name 'buttonstart' does not exist in the current context". This makes it really hard to separate functionality!

This is the whole program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using System.Windows.Forms;

namespace OCRCleanup2
{
    /// <summary>
    /// Interaction logic for Mainwindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (cam != null)
            {
                if (captureInProgress == true)
                {
                    cam.Pause();
                    buttonstart.Content = "Start";
                }
                else
                {
                    cam.Start();
                    buttonstart.Content = "Pause";
                }
            }
            captureInProgress = !captureInProgress;
        }
    }

    public class Logic
    {
        private Capture cam = null;
        private bool captureInProgress = false;

        public void captureEvent()
        {
            cam = new Capture();
            cam.ImageGrabbed += CamFeed;
        }

        private static void CamFeed(object sender, EventArgs arg)
        {
            Image<Bgr, Byte> frame = cam.RetrieveBgrFrame();
            imageBox.Image = frame;
        }
    }
}




This post has been edited by wartimespark: 18 September 2014 - 02:24 PM

Was This Post Helpful? 0
  • +
  • -

#15 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Classes and such

Posted 18 September 2014 - 02:23 PM

It comes with practice. Don't kick yourself if you have to re-write the OCR library a couple times. Its natural and a part of the education process.

I try to advise using two different projects in one solution. That way you have your OCR library as one project and your GUI program in another. It tends to force you to do things clean and separated. And makes it much easier to add the OCR stuff to any number of other projects. Really helps if you are making version 1 in console, version 2 in WinForms, version 3 in WPF for example.

View Postwartimespark, on 18 September 2014 - 03:18 PM, said:

One issue I am having as I shift this code around to see how it behaves:
private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (cam != null)
            {
                if (captureInProgress == true)
                {
                    cam.Pause();
                    buttonstart.Content = "Start";
                }
                else
                {
                    cam.Start();
                    buttonstart.Content = "Pause";
                }
            }
            captureInProgress = !captureInProgress;
        }

I like this functionality and I understand how it works. But, when I place it in a class other than MainWindow : Window (you can see I moved to WPF) I get the error "The name 'cam' does not exist in the current context". When I move it to the class where 'cam' does exist, I get the error "The name 'buttonstart' does not exist in the current context". This makes it really hard to separate functionality!


That's because you shouldn't be affecting the GUI from another class. Period. Ever. The main window handles the window. The other class does its job. The end. The other class should have nothing to do with GUI, not know about GUI, not care or be dependent upon the GUI.
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3