Monday, 25 November 2024

The Great Inference Adventure: From Debugging Despair to Deployment Delight

Background, Be Gone: Running Inference with ONNX and U2Net

Ever looked at an image and thought, “The background really ties this mess together”? Me neither. That’s why we’re diving into ONNX inference today—specifically how to remove backgrounds using the U^2-Net model. Whether you’re an AI pro or just here for fun, let’s explore the magic behind the scenes of turning an ONNX model into a background-removal wizard.

 Easily go from a picture with a background to an image without in roughly 20 seconds:


Follow this link for an ultra small model that runs in a browser if you want to test background removal. Unfortunately it will only work on PC as mobile browsers have too many restrictions.

For a complete working program that can be downloaded and installed on your Windows 10/11 pc please click here (download TinyBGR_Setup, unzip it, run setup.exe to install)

What is ONNX Inference?

First, ONNX (Open Neural Network Exchange) isn’t just an acronym; it’s an invitation to make AI work smarter, not harder. It lets you use pre-trained models across different platforms and frameworks—like bringing your favourite lunch to work without worrying if the microwave is compatible.

Inference, in non-jargon, means putting the AI model to work. It’s the moment your model steps onto the stage to predict, classify, or—our focus today—erase pesky image backgrounds.

Here is a representation of the model top in the ONNX model viewer showing exactly how the model expect the image input to be:


 

 

The U^2-Net Model

U^2-Net is the drama queen of image segmentation. It’s trained to identify objects in an image and separate them from the background with surgical precision. Think of it as the scalpel of AI, slicing through pixels to leave you with just what you want (and none of what you don’t).

 

Step 1: Preparing the Image

Before U^2-Net flexes its algorithmic muscles, the image needs a makeover. Here’s what you’ll do:

  1. Resize the Image: U^2-Net expects a specific size (e.g., 320x320 pixels). It’s picky, like a cat that won’t drink tap water.
  2. Normalize Pixel Values: Your image’s RGB values (0-255) must be scaled to 0-1. It’s like telling the model, “Calm down, we’re just pixels.”. 
  3. If the image is RGBA, the transparency layer needs to be removed so that only the "RGB" is left. This can be done quite easily with code. In this case here is an example for C++:

std::vector<float> PreprocessImage(
Gdiplus::Bitmap* bitmap, size_t targetWidth, size_t targetHeight) {
    std::vector<float> floatArr(targetWidth * targetHeight * 3);

    // Resize and draw image
    Gdiplus::Bitmap resizedBitmap(targetWidth, targetHeight, PixelFormat24bppRGB);
    Gdiplus::Graphics graphics(&resizedBitmap);
    graphics.DrawImage(bitmap, 0, 0, targetWidth, targetHeight);

    Gdiplus::Rect rect(0, 0, targetWidth, targetHeight);
    Gdiplus::BitmapData bitmapData;
    resizedBitmap.LockBits(&rect, Gdiplus::ImageLockModeRead,
 PixelFormat24bppRGB, &bitmapData);

    BYTE* pixels = (BYTE*)bitmapData.Scan0;
    int stride = bitmapData.Stride;

    size_t j = 0;
    for (size_t y = 0; y < targetHeight; ++y) {
        for (size_t x = 0; x < targetWidth; ++x) {
            BYTE* pixel = pixels + y * stride + x * 3;
            floatArr[j] = (pixel[2] / 255.0f - 0.485f) / 0.229f; // R
            j++;
            floatArr[j] = (pixel[1] / 255.0f - 0.456f) / 0.224f; // G
            j++;
            floatArr[j] = (pixel[0] / 255.0f - 0.406f) / 0.225f; // B
            j++;
        }
    }

    resizedBitmap.UnlockBits(&bitmapData);

    // Channel wise separation
    std::vector<float&gt floatArr2(floatArr.size());
    size_t k = 0, l = targetWidth * targetHeight, m = targetWidth * targetHeight * 2;
    for (size_t i = 0; i < floatArr.size(); i += 3) {
        floatArr2[k++] = floatArr[i];      // R
        floatArr2[l++] = floatArr[i + 1];  // G
        floatArr2[m++] = floatArr[i + 2];  // B
    }

    return floatArr2;
}

       

Step 2: Running the ONNX Model

Once the image is prepped, you feed it into the ONNX Runtime. Here’s what happens:

  1. Load the ONNX File: Ensure you’ve got the U^2-Net ONNX file handy. Loading it into your app should feel like the calm before the storm.
  2. Run Inference: This is where the magic happens—assuming you haven’t forgotten to set up the input tensor correctly (guilty as charged). A single forward pass processes the image, producing a segmentation mask. Here is the example in C++:
Here is an example of a bad output when the tensor values are off:



Gdiplus::Bitmap* RunModelInference(
Ort::Session& session, std::vector<float>& inputTensorValues,
 int targetWidth, int targetHeight) {
    // Define the known input and output names based on your model's specifications
    const char* inputName = "input.1";  // Update this name if needed
    const char* outputName = "output";  // Update this name if needed

    // Set input tensor dimensions: batch size 1, channels 3, height, width
    std::vector<int64_t> inputDims = { 1, 3, targetWidth, targetHeight };
    Ort::MemoryInfo memoryInfo = Ort::MemoryInfo::CreateCpu(
OrtDeviceAllocator, OrtMemTypeCPU);
    Ort::Value inputTensor = Ort::Value::CreateTensor<float>(
memoryInfo, inputTensorValues.data(), inputTensorValues.size(), inputDims.data(),
 inputDims.size());

    // Run inference
    auto outputTensors = session.Run(Ort::RunOptions{ nullptr }, &inputName,
 &inputTensor, 1, &outputName, 1);

    // Access output tensor data
    float* outputData = outputTensors[0].GetTensorMutableData<float>();
    int outputSize = targetWidth * targetHeight;

    // Create a grayscale image to store the output mask
    Gdiplus::Bitmap* maskBitmap = new Gdiplus::Bitmap(targetWidth, targetHeight,
 PixelFormat32bppARGB);

    // Populate mask with output values
    for (int y = 0; y < targetHeight; ++y) {
        for (int x = 0; x < targetWidth; ++x) {
            float pixelValue = outputData[
            y * targetWidth + x] * 255.0f;  // Scale to 0-255
            BYTE intensity = static_cast<BYTE>(std::clamp(pixelValue, 0.0f, 255.0f));
            Gdiplus::Color color(intensity, intensity, intensity);  // Grayscale
            maskBitmap->SetPixel(x, y, color);
        }
    }

    return maskBitmap;
}

 

Step 3: Postprocessing

If preprocessing is the starter, postprocessing is dessert. The raw output from U^2-Net isn’t exactly pretty—it’s like staring at a cryptic Rorschach test.

Here’s how to polish it:

  1. Thresholding: Convert the grayscale mask into a binary one, where the object is white, and the background is black.
  2. Apply the Mask: Use the binary mask to “cut out” the object. Cue the “ta-da” moment as the background vanishes. Some more C++:

Gdiplus::Bitmap* PostprocessOutput(
const std::vector<float>& outputTensorValues, Gdiplus::Bitmap* originalBitmap,
 size_t targetWidth, size_t targetHeight) {
    const float amplificationFactor = 255.0f;
     // Scale sigmoid outputs to the range [0, 255]

    // Generate the mask bitmap
    Gdiplus::Bitmap* maskBitmap = GenerateMaskBitmap(outputTensorValues,
 targetWidth, targetHeight, amplificationFactor);

    // Resize the mask to match original image dimensions
    Gdiplus::Bitmap* resizedMaskBitmap = new Gdiplus::Bitmap(
    originalBitmap->GetWidth(),
    originalBitmap->GetHeight(), PixelFormat32bppARGB);
    Gdiplus::Graphics graphics(resizedMaskBitmap);
    graphics.DrawImage(maskBitmap, 0, 0, originalBitmap->GetWidth(),
 originalBitmap->GetHeight());

    // Apply the resized mask to the original image
    Gdiplus::Bitmap* resultBitmap = ApplyMaskToImage(
    originalBitmap, resizedMaskBitmap);

    // Clean up
    delete maskBitmap;
    delete resizedMaskBitmap;

    return resultBitmap;
}

 

Challenges and Frustrations

Not everything goes smoothly:

  • ONNX Error Messages: These are cryptic and unhelpful. You’ll question your life choices multiple times.
  • Preprocessing Mismatches: Forgetting to normalize the image properly leads to hilarious (or horrifying) results.
  • Output Mask Issues: Sometimes the mask looks great on one image but terrible on another. It’s the “one size fits all” paradox.

 

Why Use ONNX?

Because it’s:

  • Portable: Train in one framework, run anywhere.
  • Efficient: Optimized for speed (when set up correctly).
  • Cool: Who doesn’t love a buzzword-friendly solution?

 

Conclusion

Running inference on an ONNX model, particularly U^2-Net, is like cooking: follow the recipe, improvise a bit, and expect the fire alarm to go off at least once. But when it works, it’s a chef’s kiss moment. Whether you’re removing backgrounds for professional use or just to meme your friends, the process is satisfying, educational, and occasionally exasperating—just like all things tech.

 Cheers!


 

 

 

 

 

Tuesday, 22 October 2024

Protect Yourself from Scams: Top Tips for Identifying Fraudulent Texts and Emails

Received a Weird Text or E-mail?

DO NOT USE ANY LINKS PROVIDED IN THE E-MAIL or SMS. Unknown links can mislead you or possibly get you to install malicious software on your device! If you are using a computer to read the message or e-mail, you could hover your mouse over the link and it should show you what the shortened URL actually is or where link text is going to take you, but this does not always work.


There are many ways that scammers are trying to steal your hard earned money. Two of the most prevalent are usually sent via text message or email, and sometimes a combination of both. And both methods used, lead to a website that wants you to insert your credit card information. How did they get your phone number and email? How do you spot if the site is fake?

Lets have a look at what they send and how they try to fool you into giving up your credit card details or personal information.

 

Where did they get your details?:

Most of the information used by scammers comes from a data broker that has sold your information online. This could be from anywhere that you provided your number, e-mail or both and possibly your name and address too. In today's world, many shops, websites and businesses ask people to provide various details for their records and unfortunately, once you have provided the details, you have no guarantee that they will keep it safe.
Another place that your details could be found is from when a company has had a data breach, or has been hacked, and a list of customer details has been found, sold, or exposed to the internet. This is also out of your control and could be tough to deal with as the more details a scammer has on a target, the easier it will be to fool them.

Example 1 of what they send you, the SMS:


 You receive a text or SMS message from an unknown number claiming that you have a delivery pending, but needs a clearance fee paid before the package will be sent. Included is a shortened URL so that you cannot verify where the link will take you. By using a link shortener extension or website  a short URL can be created. This is supposed to help with long URL's but can be used to hide them. The only way to see where the link leads is to click on it and see, or hover your mouse pointer over the link to view the actual address (Not possible on a cellphone though). This makes the SMS slightly more believable and in so doing hopes to fool as many people into clicking on the link as possible.


Here is where this short URL will take you, click on the image on the right to enlarge it. The scammer has used a known courier company, and has copied the logo and a few other details from the actual courier site to help fool you. There are however a few ways to find out if the web page is valid or not. Some obvious problems that you should come across:
 
1. The hamburger menu on the top left does not work.
2. The company logo is not clickable.
3. No company details, help or support info.
4. Strange URL in the address bar.
 
 Here is an edited version of the link URL, it is expired and does not work any more, but I have not put the entire link:
 
https://pub-456somerandomtextea98.r2.dev/cc.html
 
As you can see, the URL is not under the domain of the company, and uses an r2.dev as the domain extension. Some examples of a domain extension would be .org or .edu or even .gov for government sites.
 
The extension used in the scammers link is actually from a Cloudflare bucket. Here is the definition of a bucket from the Cloudflare website: Public Bucket is a feature that allows users to expose the contents of their R2 buckets directly to the Internet. What that means is that a scammer can easily create a small website inside the bucket, using the actual companies artwork, have a card payment option below, and have it available to the internet. In this way the scammer can replace the images with another companies artwork, create a new bucket and URL address, and start a new scam under a different name. 
If you do enter your bank details into the website, they will most definitely be stolen and used to purchase items or steal money from your account. And once they have your money, it will be very hard to get your money back as most banks will not cover this type of fraud.

Example 2 of what they send you, the E-mail:

 Below are two different emails from different scammers. Both included invoices, for two different products, which are paid for already. So how are they trying to scam you?



Click on the images to enlarge them for more details.

These types of e-mails are called “phishing” attacks and are used to find personal information about you, then use that to steal money from you. What the scammer is trying to do is get you to either reply to the email, which verifies that your email is active and possibly your correct name, or to get you to call the help line number provided so that they can talk to you personally. If they can talk to you personally they might be able to gather more information from you, as they will be asking detailed questions about who you are, where you live, and possibly an identification number. If you do unwittingly provide more details, the scammer will find it easier to target you in other ways.
 
There are many ways to tell that these types of emails are not from a reputable person or company:

1. The senders e-mail address and the name used in the email are different.
2. E-mails from companies that end in @gmail/@somethingelse.com instead of the official name.
3. Bad spelling and grammar.
4. Low quality images and text.

With this type of scam, they are trying to get you to think, Great!, free stuff, let's contact them and see if I can get it. Its an incentive to get you to action the scam and provide more details than you normally would.
 

What should you do?

DO NOT USE ANY LINKS PROVIDED IN THE E-MAIL or SMS. Unknown links can mislead you or possibly get you to install malicious software on your device
 

 1. Verify first if you did place the order

The first and foremost is think if you did actually buy or order something related to the email. It could be that you order a large amount of goods and services online and it might be tempting to reply to the email or phone the numbers provided. 
You can log into the website where the sale originated and view pending and current orders. . 
Most of the sites have a history of what has been ordered as well as the status of the orders. Also it is quite easy to pull a bank statement online and verify all purchases quickly. 
 
 

2. Does the email look "scammy"?

Verify that the e-mail does actually look official. This can be difficult as the scammer might have gone to the effort of making a high quality message to fool you. If you have ordered from the same company or person in the past, compare if the invoices and e-mails are similar. This however is not the best way to verify if it is a scam or not, but there could be bad spelling and grammar, which should indicate that it is a scam. Here is an example:
 

The text above comes from one of the email images listed above and does not make any sense.  Professional companies verify their sales emails and there should not be any mistakes such as this.
 

What to do if you know it is a SCAM:

 The best is to not open the e-mail or SMS. Most times you have a preview of the message and might be able to decide if it is scam related and then delete the message or e-mail straight away. If you needed to open the message as you were unsure, delete it right after deciding that it is a scam without opening any attachments or clicking on any links.

You could also go a few steps further by blocking the sender or telephone number, thereby ensuring that you cannot receive other scam messages from them. This might only help for a short while as scammers are continuously updating e-mail and phone numbers. Usually, your antivirus/scanning system of your chosen email provider will mark the e-mail as junk or malicious and automatically move the e-mail to the relevant folder or delete it. If this is not happening you can verify your mailbox settings. Or it could be possible that the scam is very new and the e-mail system needs to be updated.

Last Thoughts:

Most importantly is to pay attention to which site(s) you are entering your credit card details into. The URL might even have the padlock in the address bar to say that it is secure and verified, but this is only for the information sent between your browser and the website. It has nothing to do with what you are entering and your bank or credit card.
So be careful out there in the digital wonderland. There are many places that you might fall into a trap that can cost you money or cause extra stress in your life. The best is to double check, and if you are not sure, do not enter your credit card details.

Cheers!




 
 
 
  

Friday, 18 October 2024

Get Ahead with AI: Overcoming HR AI Bot Filters for More Interviews

 


Human Resources and AI


HR departments have been using software to screen resumes for years, and now with easy access to AI, the software can screen thousands of resumes/CV's very quickly. From a human resources standpoint this saves them a huge amount of time and effort. The job posting draft is created inside the software and can be tweaked for the position so that the correct requirements are listed.
The job posting can then be verified by the hiring manager and once confirmed it is posted online or with the recruitment agencies employed by the company. This results in a massive amount of applications being sent in, and it would be physically impossible for a small HR department to sift through and find the best applicant.


How to Beat the BOTS

Firstly, you will need to gather your files. Copy all the job listing text, or if it was advertised in a newspaper, use an image to text app, and save the text to a text file on your computer or device. The more information that the job listing has, the better, as this will help in one of the steps to follow. 
Next would be to adjust your resume/CV manually so that it is inline with the job you are applying for, listing your related experience and so on. Every job has unique qualifications, and a tailored resume maximizes the chances of passing through applicant tracking systems. Tailoring your resume ensures it is not only optimized for AI systems but also speaks directly to the employer’s specific needs, helping you stand out from generic applications. Save your newly edited resume in an easy to find location, possibly in the same folder/location where you saved the job listing text.

The next step is to open your favourite AI such as ChatGPT or Copilot and look for the upload button. What you need to do is upload the job listing, and your resume.
 
 
That was the easy part. The next step is critical though. You need to explain in a prompt to your chosen AI what it needs to do with the two files that you uploaded. You need the AI to detect and highlight the most important keywords in the job listing and rewrite your resume to optimise it for the job you are applying to.
 
Here is an example of the prompt that I used:
 
"You are an expert in crafting resumes optimized to make resumes stand out when being reviewed by applicant tracking systems. Attached is the job description to which I'm applying, and my most recent resume. First, highlight keywords present in the job description that are lacking in my resume. Then, note which keywords may be the most difficult to incorporate into a rewrite of my current resume bullets. Finally, ask me any questions about my career experience to help you be able to incorporate those additional keywords as I will eventually have you rewrite my resume."

Your chosen AI will then get to work analysing your two files and and list all the requests from the prompt.


As you can see from the image above, ChatGPT started listing the missing keywords and under-represented information required by the job listing. I am not a Siemens engineer so there were many issues in the list from ChatGPT. But this is just an example of what AI can do for your resume so lets continue.

Your next task will be to answer the questions listed by the AI so that it can use that information to update and add it to your resume. Answer the questions with lots of detail so that the AI can use your experience and knowledge to build the best resume possible. While AI can help with the technicalities of resume optimization, it's essential to ensure that the experience and skills listed remain truthful and aligned with your actual capabilities. Finish by telling your chosen AI that you have completed answering the questions. Next you will need to prompt the AI again to update and rewrite your resume by sending it another prompt. Here is an example:

"Re-write the contents of my resume seamlessly incorporating the important keywords you originally highlighted into my bullet points accompanied by strong action verbs. Assure my bullet points are no more than 2 lines (but ideally one line each) and that the resume is optimized for the job description."

After a few seconds you should see a new resume being generated for you with all the included keywords and highlights from the job listing. From there you can easily copy and paste the text from the AI into a new document and start building a new and improved resume that will hopefully help land you the interview. 

Conclusion

One of the problems with systems like this is the fact that there is no human intervention after the HR software has been used to create a job listing for a new position. Many things can go wrong here, an incorrectly configured system could quite easily disregard almost all the resumes sent in and deny your resume the chance it should get.
Many other people are also using AI software to help improve their resumes too, which means that a lot of the resumes are going to end up having the same details and keywords. But if you do not do this, you are at a disadvantage as the HR bot can only do what it was configured for, and that is to analyse the text on everyone's resume and select the best match.
Basically, what is happening is you are now using AI to fight AI, and hopefully get that much needed interview. If you cannot get interviews, you cannot be hired. So think carefully when typing in the prompt to ask AI what you want it to do. The more specific and detailed you are, the better the resulting resume will be.  

"Applicant Tracking System (ATS)," "AI for job applications," "Resume optimization tips," "Beat resume screening bots," "AI-powered resume writing."
Cheers!






The Great Inference Adventure: From Debugging Despair to Deployment Delight

Background, Be Gone: Running Inference with ONNX and U2Net Ever looked at an image and thought, “The background really ties this mess to...