霍夫来一发,变换!

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.net.*;
import java.util.*;
import java.io.*;
import java.awt.Color.*;
import java.lang.Math.*;

/**
 *Hough is an algorithm to apply a hough transform to an image
 *@author:Timothy Sharman
 *@see code.iface.hough
 */

public class Hough extends Thread{

  //the width and height of the output image

  private int d_w;
  private int d_h;
  private int [] dest_1d;
  private int [] hough_1d;

  //Create a new version of twoimages to put the output images in
 
  TwoImages twoimages = new TwoImages();

  /**
   *Applies the hough transform to the input image
   *@param src_1d The source image as a pixel array
   *@param width width of the destination image in pixels
   *@param height height of the destination image in pixels
   *@param threshold The threshold to be applied to the hough space
   *@param scale A scale value to apply ot the hough space
   *@param offset An offset value to apply to the hough space
   *@return An object containing the hough space image, and the line image
   */

  //Tim's Hough Transform Algorithm
  /*a) assume the image is grey level (hence RR=GG=BB)
    b) use value &0x000000ff to get the BB value
    c) find each edge pixel
    d) apply the line equation and update hough array
    e) apply threshold to hough array to find line
    f) draw lines
    g) Return the hough space and the line image
    */

  public TwoImages apply_hough(int [] src_1d, int width, int height,
                   float threshold, float scale, float offset){
   
    d_w = width;
    d_h = height;
    int [][] tmp_2d;
    int [][] dest_2d;
    int [][] src_2d = new int [d_w][d_h];
    int h_w = 500;
    //During processing h_h is doubled so that -ve r values
    //can be easily dealt with
    int h_h;
    int tmp;
    int src_rgb;
    int centre_x = d_w / 2;
    int centre_y = d_h / 2;
    int thresh;

    //Work out how the hough space is quantized

    double theta_step = Math.PI / h_w;

    tmp = Math.max(d_h,d_w);
    h_h = (int) (Math.sqrt(2)*tmp);
    hough_1d = new int[2*h_w*h_h];
//System.out.println("Hough array w: "+h_w+" height: "+2*h_h);

    //Create the hough array and initialize to zero
    tmp_2d = new int [h_w][2*h_h];
    for(int i = 0; i < h_w; i++){
      for(int j = 0; j < 2*h_h; j++){
    tmp_2d[i][j] = 0;
      }
    }

    //Initialize the output arrays to black
    dest_1d = new int[d_w*d_h];
    for(int i = 0; i < dest_1d.length; i++){
      dest_1d[i] = Color.black.getRGB();
    }
    dest_2d = new int [d_w][d_h];
    for(int i = 0; i < d_w; i++){
      for(int j = 0; j < d_h; j++){
    dest_2d[i][j] = Color.black.getRGB();
      }
    }

    //Find edge points and vote in array

    //First convert input from 1_d to 2_d for ease of processing
    //Pixels are flipped here
    for(int i = 0; i < d_w; i++){
      for(int j = 0; j < d_h; j++){
    src_2d[i][(d_h-j)-1] = src_1d[i+(j*d_w)];
      }
    }

    //Now find edge points and update hough array
    for(int i = 0; i < d_w; i++){
      for(int j = 0; j < d_h; j++){
    src_rgb = src_2d[i][j] & 0x000000ff;
    if(src_rgb == 0){
      //Background found
    }
    else {

      // Edge pixel found
      for(int k = 0; k < h_w; k++){

        //Work out the r values for each theta step
        tmp = (int) (((i-centre_x)*Math.cos(k*theta_step)) +
             ((j-centre_y)*Math.sin(k*theta_step)));

        //Move all values into positive range for display purposes
//if (tmp== -1 && k ==150 ) System.out.println("LOW  ij: "+i+" "+j);
//if (tmp==  0 && k ==150 ) System.out.println("ON   ij: "+i+" "+j);
//if (tmp==  1 && k ==150 ) System.out.println("HIGH ij: "+i+" "+j);
        tmp = tmp + h_h;
        if (tmp < 0 || tmp >= 2*h_h) continue;

        //Increment hough array
        tmp_2d[k][tmp]++;
      }
    }
      }
    }
   
    //Now translate the hough array back into 1_d so that it can be displayed
    int high = 0;
    for(int i = 0; i < h_w; i++){
      for(int j = 0; j < 2*h_h; j++){
    hough_1d[i+(j*h_w)] = tmp_2d[i][j];

    //Find the max hough value for the thresholding operation
    if(tmp_2d[i][j] > high){
      high = tmp_2d[i][j];
    }
      }
    }

    //Set the threshold limit
    thresh = (int) (threshold * high);
//System.out.println("Threshold: "+threshold+" Max: "+high);

    // Search for local peaks above threshold to draw
    boolean draw = false;
    int k;
    int l;
    int dt;     // test theta
    int dr;     // test offset
    for(int i = 0; i < h_w; i++){
      for(int j = 0; j < 2*h_h; j++){

    // only consider points above threshold
    if(tmp_2d[i][j] >= thresh){

//if (0.2*h_w < i && i < 0.3*h_w)
//System.out.println("Point at: "+i+" "+j+" value: "+tmp_2d[i][j]);

          // see if local maxima
          draw = true;
          int peak = tmp_2d[i][j];
          for(k = -1; k < 2; k++){
            for(l = -1; l < 2; l++){
                if (k==0 && l==0) continue;
                dt = i+k;
                dr = j+l;
                if (dr < 0 || dr >= 2*h_h) continue;
                if (dt < 0) dt = dt + h_w;               
                if (dt >= h_w) dt = dt - h_w;
                if (tmp_2d[dt][dr] > peak)
                {
//if (0.2*h_w < i && i < 0.3*h_w)
//System.out.println("Bigger Point at: "+dt+" "+dr+" value: "+tmp_2d[dt][dr]);
                   draw = false;
                   break;
                }                               
            }
          }
          if (!draw) continue;
//if (0.2*h_w < i && i < 0.3*h_w)
//System.out.println("Drawing: "+i+" "+j+" value: "+tmp_2d[i][j]);

        //Draw edges in output array
            double tsin = Math.sin(i*theta_step);
            double tcos = Math.cos(i*theta_step);
        if (i <= h_w/4 || i >= (3*h_w)/4) {
              for(int y = 0; y < d_h; y++){
            int x = (int) (((j-h_h) - ((y-centre_y)*tsin)) / tcos) + centre_x;
            if(x < d_w && x >= 0){
          dest_2d[x][d_h-y-1] = 0xff0000ff;
            }
          }
        }
        else {
            for(int x = 0; x < d_w; x++){
              int y = (int) (((j-h_h) - ((x-centre_x)*tcos)) / tsin) + centre_y;
              if(y < d_h && y >= 0){
            dest_2d[x][d_h-y-1] = 0xff0000ff;
              }
            }
        }
    }
      }
    }

    //Convert the output array from 2_d to 1_d
    for(int i = 0; i < d_w; i++){
      for(int j = 0; j <d_h; j++){
    dest_1d[i+(j*d_w)] = dest_2d[i][j];
      }
    }
   
    //Apply scaling and offset to hough space
    for(int i = 0; i < hough_1d.length; i++){

      int answer = (int) ((scale * ((double)hough_1d[i])) + offset);

      //clip to 0 ... 256
      if (answer < 0){
                  answer = 0;
      } else if  (answer > 255){
                  answer = 255;
      }

      hough_1d[i] = 0xff000000 | (answer + (answer << 16) + (answer << 8));
    }

    //Return the two output images
    twoimages. image1 = hough_1d;
    twoimages. image2 = dest_1d;
    return twoimages;
  }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值