Showing posts with label image-processing. Show all posts
Showing posts with label image-processing. Show all posts

Thursday, September 13, 2018

Feature extraction and take color histogram

Leave a Comment

I am working on an image processing feature extraction. I have a photo of a bird in which I have to extract bird area and tell what color the bird has. I used canny feature extraction method to get the edges of a bird.

How to extract only bird area and make the background to blue color?

openCv solution should also be fine.

enter image description here

import skimage import numpy as np %matplotlib inline import matplotlib.pyplot as plt  import os filename = os.path.join(os.getcwd(),'image\image_bird.jpeg') from skimage import io bird =io.imread(filename,as_grey=True) plt.imshow(bird) 

enter image description here

from skimage import feature edges = feature.canny(bird,sigma=1) plt.imshow(edges ) 

enter image description here

Actual bird image can be taken from bird link

2 Answers

Answers 1

  1. Identify the edges of your imageSobel edge map

  2. Binarize the image via automatic thresholdingbinarized edge map

  3. Use contour detection to identify black regions which are inside a white region and merge them with the white region. (Mockup, image may slightly vary) Mockup of the merged mask

  4. Use the created image as mask to color the background and color it final image This can be done by simply setting each background pixel (black) to its respective color.

As you can see, the approach is far from perfect, but should give you a general idea about how to accomplish your task. The final image quality might be improved by slightly eroding the map to tighten it to the contours of the bird. You then also use the mask to calculate your color histogram by only taking foreground pixels into account. Edit: Look here:

  1. Eroded mask

eroded mask

  1. Final image

Final image with eroded mask

Answers 2

According to this article https://www.pyimagesearch.com/2016/04/11/finding-extreme-points-in-contours-with-opencv/ and this question CV - Extract differences between two images

I wrote some python code as below. As my predecessor said it is also far from perfect. The main disadvantages of this code are constants value to set manually: minThres (50), maxThres(100), dilate iteration count and erode iteration count.

import cv2 import numpy as np  windowName = "Edges" pictureRaw = cv2.imread("bird.jpg")  ## set to gray pictureGray = cv2.cvtColor(pictureRaw,  cv2.COLOR_BGR2GRAY)  ## blur pictureGaussian = cv2.GaussianBlur(pictureGray, (7,7), 0)  ## canny edge detector - you must specify threshold values pictureCanny = cv2.Canny(pictureGaussian, 50, 100)  ## perform a series of erosions + dilations to remove any small regions of noise pictureDilate = cv2.dilate(pictureCanny, None, iterations=20) pictureErode = cv2.erode(pictureDilate, None, iterations=5)  ## find the nozero regions in the erode imask2 = pictureErode>0  ## create a Mat like pictureRaw canvas = np.full_like(pictureRaw, np.array([255,0,0]), dtype=np.uint8)  ## set mask  canvas[imask2] = pictureRaw[imask2] cv2.imwrite("result.png", canvas) 
Read More

Monday, September 3, 2018

Python OCR: ignore signatures in documents

Leave a Comment

I'm trying to do OCR of a scanned document which has handwritten signatures in it. See the image below.

enter image description here

My question is simple, is there a way to still extract the names of the people using OCR while ignoring the signatures? When I run Tesseract OCR it fails to retrieve the names. I tried grayscaling/blurring/thresholding, using the code below, but without luck. Any suggestions?

image = cv2.imread(file_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = cv2.GaussianBlur(image, (5, 5), 0) image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] 

4 Answers

Answers 1

You can use scikit-image's Gaussian filter to blur thin lines first (with an appropriate sigma), followed by binarization of image (e.g., with some thresholding function), then by morphological operations (such as remove_small_objects or opening with some appropriate structure), to remove the signatures mostly and then try classification of the digits with sliding window (assuming that one is already trained with some blurred characters as in the test image). The following shows an example.

from skimage.morphology import binary_opening, square from skimage.filters import threshold_minimum from skimage.io import imread from skimage.color import rgb2gray from skimage.filters import gaussian  im = gaussian(rgb2gray(imread('lettersig.jpg')), sigma=2) thresh = threshold_minimum(im) im = im > thresh im = im.astype(np.bool) plt.figure(figsize=(20,20)) im1 = binary_opening(im, square(3)) plt.imshow(im1) plt.axis('off') plt.show()     

enter image description here

[EDIT]: Use Deep Learning Models

Another option is to pose the problem as an object detection problem where the alphabets are objects. We can use deep learning: CNN/RNN/Fast RNN models (with tensorflow/keras) for object detection or Yolo model (refer to the this article for car detection with yolo model).

Answers 2

I suppose the input pictures are grayscale, otherwise maybe the different color of the ink could have a distinctive power.

The problem here is that, your training set - I guess - contains almost only 'normal' letters, without the disturbance of the signature - so naturally the classifier won't work on letters with the ink of signature on them. One way to go could be to extend the training set with letters of this type. Of course it is quite a job to extract and label these letters one-by-one.

You can use real letters with different signatures on them, but it might be also possible to artificially generate similar letters. You just need different letters with different snippets of signatures moved above them. This process might be automated.

Answers 3

You may try to preprocess the image with morphologic operations.

You can try opening to remove the thin lines of the signature. The problem is that it may remove the punctuation as well.

image = cv2.imread(file_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5)) image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel) 

You may have to alter the kernel size or shape. Just try different sets.

Answers 4

You can try other OCR providers for the same task. For example, https://cloud.google.com/vision/ try this. You can upload an image and check for free.

You will get a response from API from where you can extract the text which you need. Documentation for extracting that text is also given on the same webpage.

Check out this. this will help you in fetching that text. this is my own answer when I faced the same problem. Convert Google Vision API response to JSON

enter image description here

Read More

Friday, August 24, 2018

Converting 360 degree view to equirectangular in node js?

Leave a Comment

I have been trying to convert the 360 degree camera, single fish eye image, to equirectangular viewer in node js for the past two days. In stackoverflow, the same question is asked and answered in pseudo code. I have been trying to convert pseudo code to node js and cleared some errors. Now the project runs without error but the output image is blank.

From that pseudo, I dont know the polar_w, polar_h and geo_w, geo_h, geo and polar value, so, it gave static value to show the output. Here is a link which i followed to convert pseudo code to node js. How to convert spherical coordinates to equirectangular projection coordinates?.

Here is the code I tried for converting spherical image to equirectangular viewer:

 exports.sphereImage=(request, response)=>{    var Jimp = require('jimp');     // Photo resolution  var img_w_px = 1280; var img_h_px = 720;  var polar_w = 1280; var polar_h = 720; var geo_w = 1280; var geo_h = 720;  var img_h_deg = 70; var img_w_deg = 30;    // Camera field-of-view angles  var img_ha_deg = 70; var img_va_deg = 40;     // Camera rotation angles   var  hcam_deg = 230;  var  vcam_deg = 60;    // Camera rotation angles in radians   var hcam_rad = hcam_deg/180.0*Math.PI;  var vcam_rad = vcam_rad/180.0*Math.PI;   // Rotation around y-axis for vertical rotation of camera    var rot_y = [     [Math.cos(vcam_rad), 0, Math.sin(vcam_rad)],    [0, 1, 0],   [-Math.sin(vcam_rad), 0, Math.cos(vcam_rad)]      ];   // Rotation around z-axis for horizontal rotation of camera    var rot_z = [   [Math.cos(hcam_rad), -Math.sin(hcam_rad), 0],  [Math.sin(hcam_rad), Math.cos(hcam_rad), 0],  [0, 0, 1]   ];     Jimp.read('./public/images/4-18-2-42.jpg', (err, lenna) => {       polar = new Jimp(img_w_px, img_h_px);     geo = new Jimp(img_w_px, img_h_px);    for(var i=0; i<img_h_px; ++i)   {   for(var j=0; j<img_w_px; ++j)   {     // var p = img.getPixelAt(i, j);      var p = lenna.getPixelColor(i, j)     // var p = getPixels(img, { x: i, y: j })      // Calculate relative position to center in degrees     var p_theta = (j - img_w_px / 2.0) / img_w_px * img_w_deg / 180.0 * Math.PI;     var p_phi = -(i - img_h_px / 2.0) / img_h_px * img_h_deg / 180.0 *Math. PI;      // Transform into cartesian coordinates     var p_x = Math.cos(p_phi) * Math.cos(p_theta);     var p_y = Math.cos(p_phi) * Math.sin(p_theta);     var p_z = Math.sin(p_phi);     var p0 = {p_x, p_y, p_z};      // Apply rotation matrices (note, z-axis is the vertical one)     // First vertically     var p1 = rot_y[1][2][3] * p0;     var p2 = rot_z[1][2][3] * p1;      // Transform back into spherical coordinates     var theta = Math.atan2(p2[1], p2[0]);     var phi = Math.asin(p2[2]);      // Retrieve longitude,latitude     var longitude = theta / Math.PI * 180.0;     var latitude = phi / Math.PI * 180.0;      // Now we can use longitude,latitude coordinates in many different      projections, such as:     // Polar projection     {         var polar_x_px = (0.5*Math.PI + phi)*0.5 * Math.cos(theta)     /Math.PI*180.0 * polar_w;         var polar_y_px = (0.5*Math.PI + phi)*0.5 * Math.sin(theta)      /Math.PI*180.0 * polar_h;         polar.setPixelColor(p, polar_x_px, polar_y_px);     }     // Geographical (=equirectangular) projection     {         var geo_x_px = (longitude + 180) * geo_w;         var geo_y_px = (latitude + 90) * geo_h;         // geo.setPixel(geo_x_px, geo_y_px, p.getRGB());         geo.setPixelColor(p, geo_x_px, geo_y_px);     }       // ...  } }    geo.write('./public/images/4-18-2-42-00001.jpg');  polar.write('./public/images/4-18-2-42-00002.jpg');     });   } 

And tried another method by slicing image into four parts to detect car. Sliced image into four parts using image-slice module and to read and write jimp module is used. But unfortunately cars not detected properly.

Here is the code i used for slicing image:

 exports.sliceImage=(request, response)=>{  var imageToSlices = require('image-to-slices'); var lineXArray = [540, 540]; var lineYArray = [960, 960]; var source = './public/images/4-18-2-42.jpg'; // width: 300, height: 300  imageToSlices(source, lineXArray, lineYArray, {     saveToDir: './public/images/',     clipperOptions: {         canvas: require('canvas')     }     }, function() {     console.log('the source image has been sliced into 9 sections!'); });    }//sliceImage  

And for detect car from image i used opencv4nodejs. Cars are not detected properly. here is the code i used for detect car:

   function runDetectCarExample(img=null){         if(img==null){           img = cv.imread('./public/images/section-1.jpg');     }else     {          img=cv.imread(img);     }         const minConfidence = 0.06;          const predictions = classifyImg(img).filter(res => res.confidence > minConfidence && res.className=='car');          const drawClassDetections = makeDrawClassDetections(predictions);          const getRandomColor = () => new cv.Vec(Math.random() * 255, Math.random() * 255, 255);          drawClassDetections(img, 'car', getRandomColor);         cv.imwrite('./public/images/section-'+Math.random()+'.jpg', img);         var name="distanceFromCamera";         var focalLen= 1.6 ;//Focal length in mm         var realObjHeight=254 ;//Real Height of Object in mm         var cameraFrameHeight=960;//Height of Image in pxl         var imgHeight=960;//Image Height in pxl         var sensorHeight=10;//Sensor height in mm         var R = 6378.1 //#Radius of the Earth         var brng = 1.57 //#Bearing is 90 degrees converted to radians.         var hc=(200/100);//Camera height in m         predictions             .forEach((data)=> {                  // imgHeight=img.rows;//Image Height in pxl                 // realObjHeight=data.rect.height;                 // data.rect[name]=((focalLen)*(realObjHeight)*           (cameraFrameHeight))/((imgHeight)*(sensorHeight));                  var dc=(((data.rect.width * focalLen) / img.cols)*2.54)*100; // meters                 console.log(Math.floor(parseInt(data.rect.width)));                 // var dc=((Math.floor(parseInt(data.rect.width)* 0.264583) * focalLen) / img.cols); // mm                   var lat1=13.0002855;//13.000356;                 var lon1=80.2046441;//80.204632;                 // Gate 13.0002855,80.2046441                 // Brazil Polsec : -19.860566, -43.969436                 // var d=Math.sqrt((dc*dc)+(hc*hc));                 // d=(data.rect[name])/1000;                 data.rect[name]=d=dc/1000;                 lat1 =toRadians(lat1);                 lon1 = toRadians(lon1);                 brng =toRadians(90);                 // lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) +                 //      Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng));                  // lon2 = lon1 +               Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),                 //              Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));           var lat2 = Math.asin(Math.sin(lat1) * Math.cos(d/6371) +                       Math.cos(lat1) * Math.sin(d/6371) * Math.cos(brng));          var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(d/6371) * Math.cos(lat1),                               Math.cos(d/6371) - Math.sin(lat1) * Math.sin(lat2));                  lat2 = toDegrees(lat2);                 lon2 = toDegrees(lon2);                 data.rect['latLong']=lat2+','+lon2;                 // console.log(brng);              });             response.send(predictions);         cv.imshowWait('img', img);     }; 

here is the fish eye image which need to be converted to equirectangular.

Any help much appreciated pls....

1 Answers

Answers 1

You are asking how to convert a 360deg fish-eye projection to an equirectangular projection.

In order to do this, for every pixel on the fish-eye image you need to know where to place in onto the output image.

Your input image is 1920x1080, let us assume you want to output it to an equirectangular projection of the same size.

The input circle mapping is defined as:

cx = 960; // center of circle on X-axis cy = 540; // center of circle on Y-axis radius = 540; // radius of circle 

If you have a pixel at (x,y) in the input image, then we can calculate the spherical coordinates using:

dx = (x - cx) * 1.0 / radius; dy = (y - cy) * 1.0 / radius; theta_deg = atan2(dy, dx) / MATH_PI * 180; phi_deg = acos(sqrt(dx*dx + dy*dy)) / MATH_PI * 180; outputx = (theta_deg + 180) / 360.0 * outputwidth_px; outputy = (phi_deg + 90) / 180.0 * outputheight_px; 

So there we translated (x,y) from the fish-eye image to the (outputx,outputy) in the equirectangular image. In order to not leave the implementation as the dreaded "exercise to the reader", here is some sample Javascript-code using the Jimp-library as used by the OP:

var jimp = require('jimp'); var inputfile = 'input.png'; jimp.read(inputfile, function(err, inputimage) {     var cx = 960;     var cy = 540;     var radius = 540;     var inputwidth = 1920;     var inputheight = 1080;     var outputwidth = 1920;     var outputheight = 1080;     new jimp(outputwidth, outputheight, 0x000000ff, function(err, outputimage)     {         for(var y=0;y<inputheight;++y)         {             for(var x=0;x<inputwidth;++x)             {                 var color = inputimage.getPixelColor(x, y);                 var dx = (x - cx) * 1.0 / radius;                 var dy = (y - cy) * 1.0 / radius;                 var theta_deg = Math.atan2(dy, dx) / Math.PI * 180;                 var phi_deg = Math.acos(Math.sqrt(dx*dx + dy*dy)) / Math.PI * 180;                 var outputx = Math.round((theta_deg + 180) / 360.0 * outputwidth);                 var outputy = Math.round((phi_deg + 90) / 180.0 * outputheight);                 outputimage.setPixelColor(color, outputx, outputy);             }         }         outputimage.write('output.png');     }); }); 

Note that you will still need to do blending of the pixel with neighbouring pixels (for the same reason as when you're resizing the image).

Additionally, in your case, you only have half of the sphere (you can't see the sun in the sky). So you would need to use var outputy = Math.round(phi_deg / 90.0 * outputheight). In order to keep the right aspect ratio, you might want to change the height to 540.

Also note that the given implementation may not be efficient at all, it's better to use the buffer directly.

Anyway, without blending I came up with the result as demonstrated here: equirectangular projection


So in order to do blending, you could use the simplest method which is the nearest neighbour approach. In that case, you should invert the formulas in the above example. Instead of moving the pixels from the input image to the right place in the output image, you can go through every pixel in the output image and ask which input pixel we can use for that. This will avoid the black pixels, but may still show artifacts:

var jimp = require('jimp'); var inputfile = 'input.png'; jimp.read(inputfile, function(err, inputimage) {     var cx = 960;     var cy = 540;     var radius = 540;     var inputwidth = 1920;     var inputheight = 1080;     var outputwidth = 1920;     var outputheight = 1080/2;     var blendmap = {};     new jimp(outputwidth, outputheight, 0x000000ff, function(err, outputimage)     {         for(var y=0;y<outputheight;++y)         {             for(var x=0;x<outputwidth;++x)             {                 var theta_deg = 360 - x * 360.0 / outputwidth - 180;                 var phi_deg = 90 - y * 90.0 / outputheight;                 var r = Math.sin(phi_deg * Math.PI / 180)                 var dx = Math.cos(theta_deg * Math.PI / 180) * r;                 var dy = Math.sin(theta_deg * Math.PI / 180) * r;                 var inputx = Math.round(dx * radius + cx);                 var inputy = Math.round(dy * radius + cy);                 outputimage.setPixelColor(inputimage.getPixelColor(inputx, inputy), x, y);             }         }         outputimage.write('output.png');     }); }); 

For reference, in order to convert between Cartesian and Spherical coordinate systems. These are the formulas (taken from here). Note that the z is in your case just 1, a so-called "unit" sphere, so you can just leave it out of the equations. You should also understand that since the camera is actually taking a picture in three dimensions, you also need formulas to work in three dimensions.

Spherical to Cartesian and Cartesian to Spherical

Here is the generated output image:

Output image using nearest neighbour mapping

Since I don't see your original input image in your question anymore, in order for anyone to test the code from this answer, you can use the following image:

Input image

Run the code with:

mkdir /tmp/test cd /tmp/test npm install --permanent jimp cat <<EOF >/tmp/test/main.js ... paste the javascript code from above ... EOF curl https://i.stack.imgur.com/0zWt6.png > input.png node main.js 

Note: In order to further improve the blending, you should remove the Math.round. So for instance, if you need to grab a pixel at x is 0.75, and the pixel on the left at x = 0 is white, and the pixel on the right at x = 1 is black. Then you want to mix both colors into a dark grey color (using ratio 0.75). You would have to do this for both dimensions simultaneously, if you want a nice result. But this should really be in a new question imho.

Read More

Thursday, June 21, 2018

Take Snapshot of Webpage and Compare To Source

Leave a Comment

EDITED BETTER VERSION OF MY QUESTION:

1) I want to be able to take a screenshot of a URL at two different times, compare the images, and highlight the differences, if any. Has to be done via a PHP-based web app.

2) I also want a user to be able to submit a URL, which then takes a screenshot, and then using a drawing tool, highlight the section of the URL that they wish to be monitored - much like VisualPing.io.

ORIGINAL QUESTION: I want to be able to monitor just a specific section of a web page (rather than entire page). So essentially, this is what what I want a user to be able to do in an app I'm creating:

1) Enter the URL of any web page in a form field and submit. 2) A snapshot of that URL is taken and image is shown on page. 3) They can then highlight just a section of that screenshot using an overlay (the part that they wish to monitor 4) System then stores that, then using cron, pings that URL, downloads source, compares ONLY the code of the section that user highlighted, then emails user if there's a change in that specific section.

Now, the parts that I'm not sure of, is...

a) How to let someone draw on an image on the website b) Then store that section and somehow connect it back to the source of the page, so that... c) later when a file_get_contents or curl of that URL is done and source is retrieved, then same section of source is compared to highlighted part of image.

See VisualPing.io - they already do this. I want similar functionality. There are already a couple of websites like VisualPing that do this, and I need to implement that for my project.

Sorry about the complex requirement. And this has to be done in PHP.

Thanks!

2 Answers

Answers 1

I do not think that you will find a ready solution to your problem.

But I can suggest what you should do.

Parse web pages via CLI. I usually used PhantomJS, but project development is stopped now. I used this solution in my pet project. So, you can install PhantomJS, implement .js script and call it from your PHP script. Then you can use output image as you wish. For example, you can compare this with a reference picture pixel by pixel.

Answers 2

It seems like you already found the solution at VisualPing.io.

I'm guessing you're looking for a free option and that's why you don't want to use VisualPing.

Wachete does the same thing. You can have them monitor up to 5 web pages on the free plan. And yes, you can select specific parts to of the page to watch for. Some other honorbale mentions if you will are (https://changetower.com/ and https://versionista.com/).

Read More

Wednesday, May 30, 2018

How to find corners on a Image using OpenCv

Leave a Comment

I´m trying to find the corners on a image, I don´t need the contours, only the 4 corners. I will change the perspective using 4 corners.

I´m using Opencv, but I need to know the steps to find the corners and what function I will use.

My images will be like this:(without red points, I will paint the points after) enter image description here

EDITED:

After suggested steps, I writed the code: (Note: I´m not using pure OpenCv, I´m using javaCV, but the logic it´s the same).

// Load two images and allocate other structures (I´m using other image)     IplImage colored = cvLoadImage(             "res/scanteste.jpg",             CV_LOAD_IMAGE_UNCHANGED); 

enter image description here

    IplImage gray = cvCreateImage(cvGetSize(colored), IPL_DEPTH_8U, 1);     IplImage smooth = cvCreateImage(cvGetSize(colored), IPL_DEPTH_8U, 1);      //Step 1 - Convert from RGB to grayscale (cvCvtColor)     cvCvtColor(colored, gray, CV_RGB2GRAY); 

enter image description here

    //2 Smooth (cvSmooth)     cvSmooth( gray, smooth, CV_BLUR, 9, 9, 2, 2);  

enter image description here

    //3 - cvThreshold  - What values?     cvThreshold(gray,gray, 155, 255, CV_THRESH_BINARY); 

enter image description here

    //4 - Detect edges (cvCanny) -What values?     int N = 7;     int aperature_size = N;     double lowThresh = 20;     double highThresh = 40;          cvCanny( gray, gray, lowThresh*N*N, highThresh*N*N, aperature_size );    

enter image description here

    //5 - Find contours (cvFindContours)     int total = 0;     CvSeq contour2 = new CvSeq(null);     CvMemStorage storage2 = cvCreateMemStorage(0);     CvMemStorage storageHull = cvCreateMemStorage(0);     total = cvFindContours(gray, storage2, contour2, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);     if(total > 1){           while (contour2 != null && !contour2.isNull()) {               if (contour2.elem_size() > 0) {                 //6 - Approximate contours with linear features (cvApproxPoly)                   CvSeq points = cvApproxPoly(contour2,Loader.sizeof(CvContour.class), storage2, CV_POLY_APPROX_DP,cvContourPerimeter(contour2)*0.005, 0);                   cvDrawContours(gray, points,CvScalar.BLUE, CvScalar.BLUE, -1, 1, CV_AA);                }               contour2 = contour2.h_next();           }      }  

enter image description here

So, I want to find the cornes, but I don´t know how to use corners function like cvCornerHarris and others.

3 Answers

Answers 1

First, check out /samples/c/squares.c in your OpenCV distribution. This example provides a square detector, and it should be a pretty good start on how to detect corner-like features. Then, take a look at OpenCV's feature-oriented functions like cvCornerHarris() and cvGoodFeaturesToTrack().

The above methods can return many corner-like features - most will not be the "true corners" you are looking for. In my application, I had to detect squares that had been rotated or skewed (due to perspective). My detection pipeline consisted of:

  1. Convert from RGB to grayscale (cvCvtColor)
  2. Smooth (cvSmooth)
  3. Threshold (cvThreshold)
  4. Detect edges (cvCanny)
  5. Find contours (cvFindContours)
  6. Approximate contours with linear features (cvApproxPoly)
  7. Find "rectangles" which were structures that: had polygonalized contours possessing 4 points, were of sufficient area, had adjacent edges were ~90 degrees, had distance between "opposite" vertices was of sufficient size, etc.

Step 7 was necessary because a slightly noisy image can yield many structures that appear rectangular after polygonalization. In my application, I also had to deal with square-like structures that appeared within, or overlapped the desired square. I found the contour's area property and center of gravity to be helpful in discerning the proper rectangle.

Answers 2

At a first glance, for a human eye there are 4 corners. But in computer vision, a corner is considered to be a point that has large gradient change in intensity across its neighborhood. The neighborhood can be a 4 pixel neighborhood or an 8 pixel neighborhood.

enter image description here

In the equation provided to find the gradient of intensity, it has been considered for 4-pixel neighborhood SEE DOCUMENTATION.

Here is my approach for the image in question. I have the code in python as well:

path = r'C:\Users\selwyn77\Desktop\Stack\corner' filename = 'env.jpg'  img = cv2.imread(os.path.join(path, filename)) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)    #--- convert to grayscale  

It is a good choice to always blur the image to remove less possible gradient changes and preserve the more intense ones. I opted to choose the bilateral filter which unlike the Gaussian filter doesn't blur all the pixels in the neighborhood. It rather blurs pixels which has similar pixel intensity to that of the central pixel. In short it preserves edges/corners of high gradient change but blurs regions that have minimal gradient changes.

bi = cv2.bilateralFilter(gray, 5, 75, 75) cv2.imshow('bi',bi) 

enter image description here

To a human it is not so much of a difference compared to the original image. But it does matter. Now finding possible corners:

dst = cv2.cornerHarris(bi, 2, 3, 0.04) 

dst returns an array (the same 2D shape of the image) with eigen values obtained from the final equation mentioned HERE.

Now a threshold has to be applied to select those corners beyond a certain value. I will use the one in the documentation:

#--- create a black image to see where those corners occur --- mask = np.zeros_like(gray)  #--- applying a threshold and turning those pixels above the threshold to white ---            mask[dst>0.01*dst.max()] = 255 cv2.imshow('mask', mask) 

enter image description here

The white pixels are regions of possible corners. You can find many corners neighboring each other.

To draw the selected corners on the image:

img[dst > 0.01 * dst.max()] = [0, 0, 255]   #--- [0, 0, 255] --> Red --- cv2.imshow('dst', img) 

enter image description here

(Red colored pixels are the corners, not so visible)

In order to get an array of all pixels with corners:

coordinates = np.argwhere(mask) 

UPDATE

Variable coor is an array of arrays. Converting it to list of lists

coor_list = [l.tolist() for l in list(coor)]

Converting the above to list of tuples

coor_tuples = [tuple(l) for l in coor_list]

I have an easy and rather naive way to find the 4 corners. I simply calculated the distance of each corner to every other corner. I preserved those corners whose distance exceeded a certain threshold.

Here is the code:

thresh = 50  def distance(pt1, pt2):     (x1, y1), (x2, y2) = pt1, pt2     dist = math.sqrt( (x2 - x1)**2 + (y2 - y1)**2 )     return dist  coor_tuples_copy = coor_tuples  i = 1     for pt1 in coor_tuples:      print(' I :', i)     for pt2 in coor_tuples[i::1]:         print(pt1, pt2)         print('Distance :', distance(pt1, pt2))         if(distance(pt1, pt2) < thresh):             coor_tuples_copy.remove(pt2)           i+=1 

Prior to running the snippet above coor_tuples had all corner points: [(4, 42), (4, 43), (5, 43), (5, 44), (6, 44), (7, 219), (133, 36), (133, 37), (133, 38), (134, 37), (135, 224), (135, 225), (136, 225), (136, 226), (137, 225), (137, 226), (137, 227), (138, 226)]

After running the snippet I was left with 4 corners:

[(4, 42), (7, 219), (133, 36), (135, 224)]

UPDATE 2

Now all you have to do is just mark these 4 points on a copy of the original image.

img2 = img.copy() for pt in coor_tuples:     cv2.circle(img2, tuple(reversed(pt)), 3, (0, 0, 255), -1) cv2.imshow('Image with 4 corners', img2)  

enter image description here

Answers 3

Apply houghlines to the canny image - you will get a list of points apply convex hull to this set of points

Read More

Saturday, March 10, 2018

Image processing/restoration in Matlab

Leave a Comment

I have several images that i would like to correct from artifacts. They show different animals but they appear to look like they were folded (look at the image attached). The folds are straight and they go through the wings as well, they are just hard to see but they are there. I would like to remove the folds but at the same time preserve the information from the picture (structure and color of the wings). I am using MATLAB right now and i have tried several methods but nothing seems to work.

Initially i tried to see if i can see anything by using an FFT but i do not see a structure in the spectrum that i can remove. I tried to use several edge detection methods (like Sobel, etc) but the problem is that the edge detection always finds the edges of the wings (because they are stronger) rather than the straight lines. I was wondering if anyone has any ideas about how to proceed with this problem? I am not attaching any code because none of the methods i have tried (and described) are working.

Thank you for the help in advance.

Example

2 Answers

Answers 1

I'll leave this bit here for anyone that knows how to erase those lines without affecting the quality of the image:

a = imread('https://i.stack.imgur.com/WpFAA.jpg'); b = abs(diff(a,1,2)); b = max(b,[],3); c = imerode(b,strel('rectangle',[200,1])); 

enter image description here

Answers 2

I think you should use a 2-dimensional Fast Fourier Transform It might be easier to first use GIMP / Photoshop if a filter can resolve it.

I'm guessing the CC sensor got broken (it looks to good for old scanner problems). Maybe an electric distortion while it was reading the camera sensor. Such signals in theory have a repeating nature. I dont think this was caused by a wrong colordepth/colorspace translation

If you like to code, then you might also write a custom pixel based filter in which you take x vertical pixels (say 20 or so) compare them to the next vertical row of 20 pixels. Compare against HSL (L lightnes), not RGB. From all pixels calculate brightness changes this way.
Then per pixel check H (heu) is within range of nearby pixels take slope average of their brightness(ea take 30 pixels horizontal, calculate average brightnes of first 10 and last 10 pixels apply that brightness to center pixel 15,... //30, 15, 10 try to find what works well

Since you have whole strokes that apear brighter/darker such filter would smooth that effect out, the difficulty is to remain other patterns (the wings are less distorted), knowing what color space the sensor had might allow for a better decision as HSL, maybe HSV or so..

Read More

Monday, December 4, 2017

trying to call AxInterop.ImageEnXLibrary in .net

Leave a Comment

Here is the code:

AxImageEnXLibrary.AxImageEnX axImageEnX = new  AxImageEnXLibrary.AxImageEnX(); AxImageEnX.LoadFromFile(@"C:\Test.jpg"); 

Reference Library/DLL used :

  • AxInterop.ImageEnXLibrary.dll
  • Interop.ImageEnXLibrary.dll

I want to use functions of Class AxImageEnX but do not know how to initialize it. Come to know about GetOcx function required to be implement but its not working!

Reference link : Cannot run project

Can anyone please help me?

Thanks.

0 Answers

Read More

Sunday, September 3, 2017

ios Image text and colour enhancement filter

Leave a Comment

I am trying CIFilter and GPUImage filter to apply various effects (brightness, contrast, saturation, etc.) on an image, but I'm struggling, would need an enhancement like the one shown below:

Before Enhancement filter

Before Enhancement filter:

After Enhancement filter

After Enhancement filter

CIFilter code that I tried:

NSDictionary *options = @{ CIDetectorImageOrientation :                                [[resultImage properties] valueForKey:kCGImagePropertyOrientation] }; NSArray *adjustments = [resultImage autoAdjustmentFiltersWithOptions:options]; for (CIFilter *filter in adjustments) {     [filter setValue:resultImage forKey:kCIInputImageKey];     resultImage = filter.outputImage; } 

GPUImage Filter:

UIImage *inputImage = [UIImage imageNamed:@"Msource.png"]; GPUImageAdaptiveThresholdFilter *stillImageFilter = [[GPUImageAdaptiveThresholdFilter alloc] init]; stillImageFilter.blurRadiusInPixels = 10.0;// adjust this to tweak the blur radius of the filter, defaults to 4.0  UIImage *filteredImage = [stillImageFilter imageByFilteringImage:inputImage]; 

1 Answers

Answers 1

//Hope this helps , its in swift 3 :

        var aCIImage = CIImage();         var contrastFilter: CIFilter!;         var brightnessFilter: CIFilter!;         var gaussianBlurFilter: CIFilter!;         var pointFilter: CIFilter!;         var vignettFilter : CIFilter!;         var context = CIContext();         var outputImage = CIImage();         var newUIImage = UIImage();         var finalImage = UIImage()         DispatchQueue.main.async                         {                             self.gaussianBlurFilter = CIFilter(name: "CIExposureAdjust");                             self.gaussianBlurFilter.setValue(self.aCIImage, forKey: "inputImage")                              self.gaussianBlurFilter.setValue(NSNumber(value: sender.value), forKey: "inputEV");                              self.outputImage = self.gaussianBlurFilter.outputImage!;                              let imageRef = self.context.createCGImage(self.outputImage, from: self.outputImage.extent)                              self.newUIImage = UIImage(cgImage: imageRef!)                             self.testView?.image = self.newUIImage;                     }    //  

enter image description here

Read More

Tuesday, August 15, 2017

JavaFX ImagePane resize Bad Quality

Leave a Comment

How do I render the image with a better quality?

The node is a Pane with the css:

.imagePane {     -fx-background-repeat: no-repeat;     -fx-background-image: url('../../img/logo/icon_white.png');     -fx-background-size: cover;  } 

Image inside the application:

Image inside the application

Default Image: Default Image

3 Answers

Answers 1

I would recommend you to try to initialize a Background in the Java code. You can set the background into a pane.

Pane#setBackground(background); 

if you initialize a Background you would first initialize a BackgroundImage and a BackgroundImage needs an Image. In the constructor of the image you can define the requestedWith and requestedHeight. These are the properties in which resolution the files should be loaded. The final code could look like this.

pane.setBackground(new Background(new BackgroundImage(new Image(inputStream, 500, 500, true, true), BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, new BackgroundSize(pane.getWidth(), pane.getHeight(), false, false, false, true)))); 

In this case the image would be loaded with a resolution of 500 x 500 and resized into pane.getHeight and pane.getWith.

Answers 2

The original image is 307 X 594. You cannot expect that it would smoothly be resized down. It would be better to use something more scalable.

However it tried to load it from a java code saving ratio and with smooth scaling, it seems to crate bearable results. I do not see a way how to do it in css. So, i suggest you do rescaling programmatically.

I have a simple program here which you can use for experimenting.

import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundImage; import javafx.scene.layout.BackgroundPosition; import javafx.scene.layout.BackgroundRepeat; import javafx.scene.layout.BackgroundSize; import javafx.stage.Stage;;  public class MyImage extends Application {  @Override public void start(Stage stage) throws Exception {     AnchorPane root = new AnchorPane();      Image img = new Image("file:/image.png", 55, 0, true, true);     System.out.println("Image: " + img.getHeight() + " X " + img.getWidth());     BackgroundImage bgImage = new BackgroundImage(img, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,         BackgroundSize.DEFAULT);      Background bg = new Background(bgImage);     root.setBackground(bg);      Scene scene = new Scene(root, 600, 600);      stage.setScene(scene);     stage.show(); }  public static void main(String args[]) {      launch(args); } } 

Answers 3

The problem is nothing to do with CSS or Java code, It's an image processing issue that when you reduce the size of an image, the quality and sharpness of edge will be distorted.

As @serge mentioned, your image dimensions are 307 in height and 594 in width, so you should find the exact reduced width and height correspondent to your aspect ratio, you can use tools like Image aspect ratio and resizing calculator to find the best numbers for your purpose. I used your image on 93 X 180 pane, and the result was like this:

JavafX simple test
As you see on my Hello World! sample, the left image quality is not good enough, especially in edges and borders.

Solutions:

  1. Resize the image in your desired dimensions using tools like Photoshop. you can get more information in How To Resize An Image on Photoshop And Keep It Sharp
  2. Convert your original PNG images to a vector format like SVG.You can use some online tools like ONLINE PNG TO SVG CONVERTER

Read More

Wednesday, August 9, 2017

How to detect lines in opencv?

Leave a Comment

I am trying to detect lines in parking as shown below

Empty parking lot

What I hope to get is the clear lines and (x,y) position in the crossed line, however the result is not very promising

Parking lot with Hough Lines drawn

I guess it is due to two main reasons

  1. some lines are very broken or missing even human eyes can clearly identify them. (Even HoughLine can help to connect some missing lines since HoughLine sometimes would connect unnecessary lines together, so I 'd rather to do it manually)

  2. there are some repeated lines

The general pipeline for the work is shown as below

1. select the some specific colors (white or yellow)

import cv2 import numpy as np import matplotlib from matplotlib.pyplot import imshow from matplotlib import pyplot as plt  # white color mask img = cv2.imread(filein) #converted = convert_hls(img) image = cv2.cvtColor(img,cv2.COLOR_BGR2HLS) lower = np.uint8([0, 200, 0]) upper = np.uint8([255, 255, 255]) white_mask = cv2.inRange(image, lower, upper) # yellow color mask lower = np.uint8([10, 0,   100]) upper = np.uint8([40, 255, 255]) yellow_mask = cv2.inRange(image, lower, upper) # combine the mask mask = cv2.bitwise_or(white_mask, yellow_mask) result = img.copy() cv2.imshow("mask",mask)  

Binary image

2. repeat the dilation and erosion until the image can not be changed (reference )

height,width = mask.shape skel = np.zeros([height,width],dtype=np.uint8)      #[height,width,3] kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) temp_nonzero = np.count_nonzero(mask) while(np.count_nonzero(mask) != 0 ):     eroded = cv2.erode(mask,kernel)     cv2.imshow("eroded",eroded)        temp = cv2.dilate(eroded,kernel)     cv2.imshow("dilate",temp)     temp = cv2.subtract(mask,temp)     skel = cv2.bitwise_or(skel,temp)     mask = eroded.copy()  cv2.imshow("skel",skel) #cv2.waitKey(0) 

 After the erosion and dialation

3. apply the canny to filter the lines and use HoughLinesP to get the lines

edges = cv2.Canny(skel, 50, 150) cv2.imshow("edges",edges) lines = cv2.HoughLinesP(edges,1,np.pi/180,40,minLineLength=30,maxLineGap=30) i = 0 for x1,y1,x2,y2 in lines[0]:     i+=1     cv2.line(result,(x1,y1),(x2,y2),(255,0,0),1) print i  cv2.imshow("res",result) cv2.waitKey(0) 

After Canny

I wonder after the first step of selecting certain color, the lines are with broken and noises , I would think in this step we should do something to make the broken line a complete, less noisy line, and then try to apply something to do the Canny and Hough lines, any ideas ?

5 Answers

Answers 1

I'm not sure what exactly you are asking, since there is no question in your posting.

One nice and robust technique to detect line segments is LSD (line segment detector), available in openCV since openCV 3.

Here's some simple basic C++ code, which can probably converted to python easily:

int main(int argc, char* argv[]) {     cv::Mat input = cv::imread("C:/StackOverflow/Input/parking.png");     cv::Mat gray;     cv::cvtColor(input, gray, CV_BGR2GRAY);       cv::Ptr<cv::LineSegmentDetector> det;     det = cv::createLineSegmentDetector();        cv::Mat lines;     det->detect(gray, lines);      det->drawSegments(input, lines);      cv::imshow("input", input);     cv::waitKey(0);     return 0; } 

Giving this result:

enter image description here

Which looks better for further processing than your image (no line duplicates etc.)

Answers 2

Here is my pipeline, maybe it can give you some help.

First, get the gray image and process GaussianBlur.

img = cv2.imread('src.png') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  kernel_size = 5 blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0) 

Second, process edge detection use Canny.

low_threshold = 50 high_threshold = 150 edges = cv2.Canny(blur_gray, low_threshold, high_threshold) 

Then, use HoughLinesP to get the lines. You can adjust the parameters for better performance.

rho = 1  # distance resolution in pixels of the Hough grid theta = np.pi / 180  # angular resolution in radians of the Hough grid threshold = 15  # minimum number of votes (intersections in Hough grid cell) min_line_length = 50  # minimum number of pixels making up a line max_line_gap = 20  # maximum gap in pixels between connectable line segments line_image = np.copy(img) * 0  # creating a blank to draw lines on  # Run Hough on edge detected image # Output "lines" is an array containing endpoints of detected line segments lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),                     min_line_length, max_line_gap)  for line in lines:     for x1,y1,x2,y2 in line:     cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),5) 

Finally, draw the lines on your srcImage.

# Draw the lines on the  image lines_edges = cv2.addWeighted(img, 0.8, line_image, 1, 0) 

Here is my final performance.

Final Image:

enter image description here

Answers 3

what happens if you adjust maxLineGap or size of your erosion kernel. Alternatively, you could find the distance between lines. You would have to go though pairs of lines say ax1,ay1 to ax2,ay2 c.f. bx1,by1 to bx2,by2 you can find the point where the gradient at right angles (-1 over gradient of line) to a crosses line b. Basic school geometry and simultaneous equations, something like:

x = (ay1 - by1) / ((by2 - by1) / (bx2 - bx1) + (ax2 - ax1) / (ay2 - ay1)) # then y = by1 + x * (by2 - by1) / (bx2 - bx1) 

and compare x,y with ax1,ay1

PS you might need to add a check for the distance between ax1,ay1 and bx1,by1 as some of your lines look to be continuations of other lines and these might be eliminated by the closest point technique.

Answers 4

There are some great answers here to the first part of your question, but as for the second part (finding the line intersections) I'm not seeing a whole lot.

I'd suggest you take a look at the Bentley-Ottmann algorithm.

There are some python implementations of the algorithm here and here.

Answers 5

You can also add some intelligence to algorithm to get rid of the candidates which are not suppose to be detected as lines.. this can be done with the knowledge of physical properties of line. this might add some constraints.

Read More

Tuesday, August 16, 2016

Align two images in OpenCV

Leave a Comment

I have two images (see below). These images represent the contours of a pair of cables and were captured using laser based 3D triangulation. The first image is captured with the left camera, while the second one with the right camera. As can be seen, these images are partially overlapping. The left part on the first image partly corresponds to the left part on the second image. The same holds for the right part. I want to merge these two images into one image so that the corresponding parts overlap.

Next to these images, I also have the following information at my disposal:

  • A 3x3 homography matrix H of left and right camera
  • Intrinsic camera parameters K of left and right camera
  • Distortion coefficients D (9 of them) of left and right camera
  • Offset O of left and right camera

This data is specified below.

In Halcon, I have tried to do this using mosaicking:

  • Extract characteristic points in both images using Harris
  • Compute a projective transformation matrix from one image to the other using Ransac.
  • Apply the found projective transformation matrix.

This approach was however not successful. I am looking for a similar approach in OpenCV or Halcon or an approach (also in OpenCV or Halcon) that makes use of the calibration data I have at my disposal, such as the homography matrix and camera matrix.

Please provide ample explanations, if possible, since I am only starting out with Machine Vision.

enter image description here enter image description here

Hl := [0.00175186,   4.73083e-05, -0.00108921,        0.000780817, -0.00145615,   0.00118631,        0.0534139,   -0.030823,     1.0        ] Kl := [4578.21,   -5.05144, 759.766,        0.0,     4576.87,    568.223,        0.0,        0.0,       1.0   ] Dl := [-0.12573, 0.0533453, -0.575361, -0.0130272, 0.00348033, 0.00852617, -0.0271142, 0.0176706, -0.00575124] Ol := [0.0, 150.0]  Hr := [0.00173883, -2.94597e-05, 0.00109873,       -0.00077676, -0.0014687,   0.00121393,       -0.0653829,  -0.0443924,   1.0        ] Kr := [4591.96,  -4.55317, 1284.74,        0.0,    4591.19,     534.317,        0.0,       0.0,        1.0   ] Dr := [-0.110751, -0.349716, 3.86535, 0.017393, -0.00364957, -0.00633656, 0.0338833, -0.0212222, 0.00543694] Or := [0.0, 100.0] 

0 Answers

Read More

Sunday, July 31, 2016

Scikit-learn SVM digit recognition

Leave a Comment

I want to make a program to recognize the digit in an image. I follow the tutorial in scikit learn .

I can train and fit the svm classifier like the following.

First, I import the libraries and dataset

from sklearn import datasets, svm, metrics  digits = datasets.load_digits() n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1)) 

Second, I create the SVM model and train it with the dataset.

classifier = svm.SVC(gamma = 0.001) classifier.fit(data[:n_samples], digits.target[:n_samples]) 

And then, I try to read my own image and use the function predict() to recognize the digit.

Here is my image: enter image description here

I reshape the image into (8, 8) and then convert it to a 1D array.

img = misc.imread("w1.jpg") img = misc.imresize(img, (8, 8)) img = img[:, :, 0] 

Finally, when I print out the prediction, it returns [1]

predicted = classifier.predict(img.reshape((1,img.shape[0]*img.shape[1] ))) print predicted 

Whatever I user others images, it still returns [1]

enter image description here enter image description here

When I print out the "default" dataset of number "9", it looks like:enter image description here

My image number "9" :

enter image description here

You can see the non-zero number is quite large for my image.

I dont know why. I am looking for help to solve my problem. Thanks

6 Answers

Answers 1

My best bet would be that there is a problem with your data types and array shapes.

It looks like you are training on numpy arrays that are of the type np.float64 (or possibly np.float32 on 32 bit systems, I don't remember) and where each image has the shape (64,).

Meanwhile your input image for prediction, after the resizing operation in your code, is of type uint8 and shape (1, 64).

I would first try changing the shape of your input image since dtype conversions often just work as you would expect. So change this line:

predicted = classifier.predict(img.reshape((1,img.shape[0]*img.shape[1] )))

to this:

predicted = classifier.predict(img.reshape(img.shape[0]*img.shape[1]))

If that doesn't fix it, you can always try recasting the data type as well with

img = img.astype(digits.images.dtype).

I hope that helps. Debugging by proxy is a lot harder than actually sitting in front of your computer :)

Edit: According to the SciPy documentation, the training data contains integer values from 0 to 16. The values in your input image should be scaled to fit the same interval. (http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html#sklearn.datasets.load_digits)

Answers 2

1) You need to create your own training set - based on data similar to what you will be making predictions. The call to datasets.load_digits() in scikit-learn is loading a preprocessed version of the MNIST Digits dataset, which, for all we know, could have very different images to the ones that you are trying to recognise.

2) You need to set the parameters of your classifier properly. The call to svm.SVC(gamma = 0.001) is just choosing an arbitrary value of the gamma parameter in SVC, which may not be the best option. In addition, you are not configuring the C parameter - which is pretty important for SVMs. I'd bet that this is one of the reasons why your output is 'always 1'.

3) Whatever final settings you choose for your model, you'll need to use a cross-validation scheme to ensure that the algorithm is effectively learning

There's a lot of Machine Learning theory behind this, but, as a good start, I would really recommend to have a look at SVM - scikit-learn for a more in-depth description of how the SVC implementation in sickit-learn works, and GridSearchCV for a simple technique for parameter setting.

Answers 3

It's just a guess but... The Training set from Sk-Learn are black numbers on a white background. And you are trying to predict numbers which are white on a black background...

I think you should either train on your training set, or train on the negative version of your pictures.

I hope this help !

Answers 4

If you look at: http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html#sklearn.datasets.load_digits

you can see that each point in the matrix as a value between 0-16.

You can try to transform the values of the image to between 0-16. I did it and now the prediction works well for the digit 9 but not for 8 and 6. It doesn't give 1 any more.

from sklearn import datasets, svm, metrics import cv2 import numpy as np  # Load digit database digits = datasets.load_digits() n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1))  # Train SVM classifier classifier = svm.SVC(gamma = 0.001) classifier.fit(data[:n_samples], digits.target[:n_samples])  # Read image "9" img = cv2.imread("w1.jpg") img = img[:,:,0]; img = cv2.resize(img, (8, 8))  # Normalize the values in the image to 0-16 minValueInImage = np.min(img) maxValueInImage = np.max(img) normaliizeImg = np.floor(np.divide((img - minValueInImage).astype(np.float),(maxValueInImage-minValueInImage).astype(np.float))*16)  # Predict predicted = classifier.predict(normaliizeImg.reshape((1,normaliizeImg.shape[0]*normaliizeImg.shape[1] ))) print predicted 

Answers 5

Hi in addition to @carrdelling respond, i will add that you may use the same training set, if you normalize your images to have the same range of value. For example you could binaries your data ( 1 if > 0, 0 else ) or you could divide by the maximum intensity in your image to have an arbitrary interval [0;1].

Answers 6

You probably want to extract features relevant to to your data set from the images and train your model on them. One example I copied from here.

surf = cv2.SURF(400) kp, des = surf.detectAndCompute(img,None)

But the SURF features may not be the most useful or relevant to your dataset and training task. You should try others too like HOG or others.

Remember this more high level the features you extract the more general/error-tolerant your model will be to unseen images. However, you may be sacrificing accuracy in your known samples and test cases.

Read More