光阴冢

We make choices and life has a way of making us pay for them.

Morphing in Action 2

Oct 24, 2017   # Image Process  # Algorithm  # Code 

We have reviewed others’ codes in our project in order to work with them, and figure out the basic morphing method used in this project.

Actually, in the previous blog, I have learned the Mesh Warping. But to apply this method into infrared image processing for medical using, there is still a long way to go.

Prepare

We use OpenCV (C++ interface) to put up a framework. Other students have already finished the work about stiching, binarization, and dividing the image into different segments based on medical reserach.

And our work is to morph one segment to another standard segment we’ve got in previous work.

I’m still new to C++, so I wrote such a class to make the further work easier and clearer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Segment
{
  public:
    Segment();
    Segment(Mat inputImg);
  
    ~Segment();
  
    Mat getInput();
    Mat getBinary();
    Mat makeBinary();
    static vector<Point2f> mark(Mat img, int index);
    Mat morphing(Mat stdImg, vector<Point2f> stdMark, double rate, int index);
  
  private:
    Mat _inputImg;
    Mat _inputImg8;
    Mat _outputImg;
    Mat _inputBinary;
    vector<Point2f> _marked;
  
};

Mark and Get the Mesh

When we have 2 images to morph, we need to get the control points’ coordinates(x, y). And in an easiest way, we just sweep the image linearly to get the mesh.

  1. Get the binary image of this segment.

  2. Sweep every row, find the start point and the end point.

  3. Put control points uniformly in the row.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
dots_count = cols * (rows+1);
    mark.resize(dots_count);
    for (int i = 0; i <= nr;){
      if (i == nr){
        i--;
      }
      uchar* data = img.ptr<uchar>(i);
      flag = 0;
      tmps = 0;
      tmpe = nc - 1;
      for (int j = 0; j < nc; j++){
        if ((data[j] != 0) && !flag){
          tmps = j;
          flag = 1;
        }
        if ((data[j] != 255) && flag){
          tmpe = j;
          flag = 0;
        }
      }
      if (tmpe > nc - 3){
        tmpe = nc - 4;
      }
      tmpe += 2;
      tmps -= 2;
      for (int j = 0; j < cols; j++){
        tmpx = j*(tmpe - tmps) / float(cols-1) + tmps;
        tmpy = i;
        mark[i*cols / step + j] = Point2f(tmpx, tmpy);
        data[(int)tmpx] = 100;
      }
      i += step;
    }

Result

The Control Points

This image shows a binary image for the standard leg.

Control Points from standard image

Morphing Result

Here is the morphing result. There are still some edges and corners morphed not so good.

Result