распараллеливание растрового изображения - PullRequest
0 голосов
/ 30 июля 2011

У меня есть приложение, которое просматривает растровое изображение и вносит в него искажения. Я переписал часть обработки изображений для параллельной работы. кажется, что в искаженном растровом изображении установлена ​​только верхняя строка пикселей, остальная часть растрового изображения черная, что указывает на то, что массив, из которого было создано новое растровое изображение, почти пуст. Я думаю, что у меня проблема с зацикливанием. Я использовал executorservice для управления своими потоками и создал 2 темы. поток должен зацикливаться от 0 до bitmap.height / 2, а поток 2 должен зацикливаться от bitmap.height / 2 до bitmap.height. Может ли кто-нибудь помочь мне разобраться с проблемой зацикливания. Я не включил много кода, который обрабатывает растровое изображение, но опубликует его, если это поможет, спасибо.

.

public class MultiProcessorFilter {



    private static final String TAG = "mpf";





    public Bitmap barrel (Bitmap input, float k){
          if(input!=null){
        Log.e(TAG, "*********** bitmap input = "+input.toString());
          }
          int []arr = new int[input.getWidth()*input.getHeight()];
          // replace the j, i for loops:
          int jMax = input.getHeight();
          int jMid = jMax / 2;
          int iMax = input.getWidth();
          int iMid = iMax / 2;
          int nrOfProcessors = Runtime.getRuntime().availableProcessors();
          Log.e(TAG, "*********** NUM OF PROCESSORS = " + nrOfProcessors);
          ExecutorService threadPool = Executors.newFixedThreadPool(2);

          FutureTask<PartialResult> task1 = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(0, jMid - 1, input, k)); 
          FutureTask<PartialResult> task2 = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(jMid, jMax - 1,input, k)); 
          Log.e(TAG, "*********** about to call task1.get()");
          try{
          PartialResult result1 = task1.get();// blocks until the thread returns the result
          Log.e(TAG, "*********** just called task1.get()");
          result1.fill(arr);
          Log.e(TAG, "*********** result1 arr length = " + arr.length);

          Log.e(TAG, "*********** about to call task2.get()");
          PartialResult result2 = task2.get(); // blocks until the thread returns the result
          Log.e(TAG, "*********** just called task2.get()");
          result2.fill(arr);
          Log.e(TAG, "*********** result2 arr length = " + arr.length);
          }catch(Exception e){
              e.printStackTrace();
          }
          Bitmap dst2 = Bitmap.createBitmap(arr,input.getWidth(),input.getHeight(),input.getConfig());
          if(dst2!=null)
          Log.e(TAG, "*********** dst2 is not null" );
        return dst2;


        }




    public class PartialResult {
           int startP;
           int endP;
           int[] storedValues;

           public PartialResult(int startp, int endp, Bitmap input){

               this.startP = startp;
               this.endP = endp;
               this.storedValues = new int[input.getWidth()*input.getHeight()];
               Log.e(TAG, "*********** input  w = "+input.getWidth());
               Log.e(TAG, "*********** input dim  h = "+input.getHeight());
           }

           public void addValue(int p, int result) {
                 storedValues[p] = result;
                // Log.e(TAG, "*********** p = " + p + "result = " + result);
           }

           public void fill(int[] arr) {
               int x = 0;
              // Log.e(TAG, "*********** startP = "+startP + "  endP = " + endP);
              for (int p = startP; p < endP; p++, x++)
                 arr[p] = storedValues[p];

              Log.e(TAG, "*********** arr = " + arr[x]);
              }
           }




    public class PartialProcessing implements Callable<PartialResult> {
        int startJ;
        int endJ;

       // ... other members needed for the computation 

        public PartialProcessing(int startj, int endj, Bitmap input, float k) {

            this.startJ = startj;
            this.endJ = endj;
            this.input = input;
            this.k = k;


        }

        int [] getARGB(Bitmap buf,int x, int y){

            method for processing

        }

        //... add other methods needed for the computation that where in class Filters

        float getRadialX(float x,float y,float cx,float cy,float k){

            method for processing
          }

          float getRadialY(float x,float y,float cx,float cy,float k){

           method for processing
          }



          float calc_shift(float x1,float x2,float cx,float k){

           method for processing
          }


          void sampleImage(Bitmap arr, float idx0, float idx1)
          {

           method for processing
          }


        // this will be called on some new thread
        @Override public PartialResult call() { 

             PartialResult partialResult = new PartialResult(startJ, endJ,input);



            int p = startJ; // not 0! at the start since we don't start at j = 0
            int origPixel = 0;
            int color = 0;
            int i;
            for (int j = startJ; j <  endJ; j++){
                // Log.e(TAG, "*********** j = "+j );

                for ( i = 0; i < width; i++, p++){
                    //... copy the rest of the code
                    // Log.e(TAG, "*********** i = " + i);


             origPixel = input.getPixel(i,j);

             float x = getRadialX((float)j,(float)i,centerX,centerY,k);


             float y = getRadialY((float)j,(float)i,centerX,centerY,k);

             sampleImage(input,x,y);

             color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff);

             if(((i-centerX)*(i-centerX) + (j-centerY)*(j-centerY)) <= 5500){

                //arr[p]=color;
                 partialResult.addValue(p, color);
                // Log.e(TAG, "*********** color = " + color);

            }else{

                //arr[p]=origPixel;
                partialResult.addValue(p, origPixel);



            }

                }
                     // partialResult.addValue(p, color);
        }
            return partialResult;
    }


}

}//end of MultiProcesorFilter

.

[обновление 1]

.

07-31 13:50:29.548: ERROR/mpf(3354): *********** bitmap input = android.graphics.Bitmap@43cd2780
07-31 13:50:29.553: ERROR/mpf(3354): *********** NUM OF PROCESSORS = 1
07-31 13:50:29.553: ERROR/mpf(3354): *********** about to call task1.call()
07-31 13:50:29.558: ERROR/mpf(3354): *********** input  w = 150
07-31 13:50:29.563: ERROR/mpf(3354): *********** input  h = 150
07-31 13:50:30.348: ERROR/mpf(3354): *********** just called part1.call()
07-31 13:50:30.348: ERROR/mpf(3354): *********** result1 arr length = 22500
07-31 13:50:30.348: ERROR/mpf(3354): *********** about to call part2.()
07-31 13:50:30.353: ERROR/mpf(3354): *********** input  w = 150
07-31 13:50:30.353: ERROR/mpf(3354): *********** input  h = 150
07-31 13:50:31.143: ERROR/mpf(3354): *********** just called part2.call()
07-31 13:50:31.143: ERROR/mpf(3354): *********** result2 arr length = 22500
07-31 13:50:31.173: DEBUG/WifiService(1911): ACTION_BATTERY_CHANGED pluggedType: 2
07-31 13:50:31.183: ERROR/mpf(3354): *********** dst2 is not null
07-31 13:50:31.188: ERROR/mpf(3354): *********** bitmap input = android.graphics.Bitmap@43ccb060
07-31 13:50:31.253: DEBUG/dalvikvm(3354): GC freed 652 objects / 124416 bytes in 65ms
07-31 13:50:31.258: ERROR/mpf(3354): *********** NUM OF PROCESSORS = 1
07-31 13:50:31.258: ERROR/mpf(3354): *********** about to call task1.call()
07-31 13:50:31.258: ERROR/mpf(3354): *********** input  w = 150
07-31 13:50:31.258: ERROR/mpf(3354): *********** input  h = 150
07-31 13:50:32.093: ERROR/mpf(3354): *********** just called part1.call()
07-31 13:50:32.093: ERROR/mpf(3354): *********** result1 arr length = 22500
07-31 13:50:32.093: ERROR/mpf(3354): *********** about to call part2.()
07-31 13:50:32.098: ERROR/mpf(3354): *********** input  w = 150
07-31 13:50:32.098: ERROR/mpf(3354): *********** input  h = 150
07-31 13:50:33.078: ERROR/mpf(3354): *********** just called part2.call()
07-31 13:50:33.078: ERROR/mpf(3354): *********** result2 arr length = 22500
07-31 13:50:33.083: ERROR/mpf(3354): *********** dst2 is not null

.

[Update2]

 public void fill(int[] arr) {
               int x = 0;
               Log.e(TAG, "*********** startP = "+startP + "  endP = " + endP);

              for (int p = startP; p < endP; p++, x++){
                 arr[p] = storedValues[p];
              }

              Log.e(TAG, "*********** arr size = "+arr.length);
              Log.e(TAG, "*********** storedValues size = "+storedValues.length);
              }

           }

.

07-31 14:26:18.788: ERROR/mpf(6380): *********** just called task1.get()
07-31 14:26:18.788: ERROR/mpf(6380): *********** startP = 0  endP = 74
07-31 14:26:18.788: ERROR/mpf(6380): *********** arr size = 22500
07-31 14:26:18.788: ERROR/mpf(6380): *********** storedValues size = 22500
07-31 14:26:18.788: ERROR/mpf(6380): *********** result1 arr length = 22500
07-31 14:26:18.788: ERROR/mpf(6380): *********** about to call task2.get()
07-31 14:26:18.818: ERROR/mpf(6380): *********** just called task2.get()
07-31 14:26:18.818: ERROR/mpf(6380): *********** startP = 75  endP = 149
07-31 14:26:18.818: ERROR/mpf(6380): *********** arr size = 22500
07-31 14:26:18.818: ERROR/mpf(6380): *********** storedValues size = 22500
07-31 14:26:18.818: ERROR/mpf(6380): *********** result2 arr length = 22500
07-31 14:26:18.823: ERROR/mpf(6380): *********** dst2 is not null
07-31 14:26:18.823: ERROR/mpf(6380): *********** bitmap input = android.graphics.Bitmap@43ce62c0

.

[Update3]

public void fill(int[] arr) {

               Log.e(TAG, "*********** startP = "+startP + "  endP = " + endP);

              for (int p = startP; p < endP; p++){
                  for(int b=0;b<150;b++,x++)
                 arr[x] = storedValues[x];
              }

              Log.e(TAG, "*********** arr size = "+arr.length);
              Log.e(TAG, "*********** storedValues size = "+storedValues.length);
              Log.e(TAG, "*********** x = "+x);
              }

           }

1 Ответ

2 голосов
/ 31 июля 2011

Еще не полный ответ, но слишком большой для комментария.

Я не могу протестировать вашу программу, но для целей отладки, пожалуйста, измените этот метод:

public Bitmap barrel (Bitmap input, float k){
    if(input!=null){
       Log.e(TAG, "*********** bitmap input = "+input.toString());
    }
    int []arr = new int[input.getWidth()*input.getHeight()];
      // replace the j, i for loops:
    int jMax = input.getHeight();
    int jMid = jMax / 2;
    int iMax = input.getWidth();
    int iMid = iMax / 2;
    int nrOfProcessors = Runtime.getRuntime().availableProcessors();
    Log.e(TAG, "*********** NUM OF PROCESSORS = " + nrOfProcessors);

    PartialProcessing part1 = new PartialProcessing(0, jMid - 1, input, k); 
    PartialProcessing part2 = new PartialProcessing(jMid, jMax - 1,input, k); 
    Log.e(TAG, "*********** about to call task1.call()");
    try{
       PartialResult result1 = part1.call();// blocks until the thread returns the result
       Log.e(TAG, "*********** just called part1.call()");
       result1.fill(arr);
       Log.e(TAG, "*********** result1 arr length = " + arr.length);

       Log.e(TAG, "*********** about to call part2.()");
       PartialResult result2 = part2.call(); // blocks until the thread returns the result
       Log.e(TAG, "*********** just called part2.call()");
       result2.fill(arr);
       Log.e(TAG, "*********** result2 arr length = " + arr.length);
    }catch(Exception e){
        e.printStackTrace();
    }
    Bitmap dst2 = Bitmap.createBitmap(arr,input.getWidth(),input.getHeight(),input.getConfig());
    if(dst2!=null)
        Log.e(TAG, "*********** dst2 is not null" );
    return dst2;
}

Этобудет серийный вариант вашей программы.Запустите его и проверьте, работает ли он.

  • Если это так, у нас есть проблема с параллелизмом.
  • Если это не работает, проблема в вашей фактической реализации,не зависит от параллелизма.

почти пустой битовый массив все еще является результатом обработки

Хорошо, поэтому мы знаем, что это не параллелизм.связанные с.Давайте посмотрим на точки, где установлены пиксели.Один из них здесь, в PartialResult:

  public void fill(int[] arr) {
       int x = 0;
      // Log.e(TAG, "*********** startP = "+startP + "  endP = " + endP);
      for (int p = startP; p < endP; p++, x++)
         arr[p] = storedValues[p];

      Log.e(TAG, "*********** arr = " + arr[x]);
      }
  }

Это устанавливает элементы arr из startP в endP в некоторые сохраненные значения.Теперь, пожалуйста, взгляните на фактические значения startP и endP по сравнению с размерами storedValues и arr, и я полагаю, вы поймете, почему существует только первая строка пикселей.


После обновления 3:

Становится лучше.Теперь посмотрите, где ваш x начинается в методе fill (в старом это был 0, я не уверен насчет нового - он должен быть startP*150), и где ваш p начинается с метода call (начинается с startJ - думаю, оно должно начинаться и с startJ * 150).

...