Filtr splotowy nie działa jak powinien-Android

0

Witam,
Mam problem z właściwym działaniem filtru splotowego na Androidzie. Po zaaplikowaniu konkretnych filtrów(9-elementowa maska) wynik nie jest taki jak powinien. Blur np. działa tak jak powinien, ale filtr Laplace'a już nie, tak samo wykrywanie krawędzi. Na wynikowych obrazach powstają przekłamania, szumy.

Tego samego filtru używam na Windowsie i tu wszystko działa tak jak powinno.

Kod samego filtru z Androida:

public class ConvolutionFilter {

	public Bitmap apply_Mask(int[] mask, Bitmap image) {
		int c;
		Bitmap preview;
		preview=image;
		
		 int r=0;
         int g=0;
         int b=0;
         

         int weight=0;
         int weightSum=0;
         int counter=0;
         
         for (int i = 0; i < mask.length; i++)
         {
             weightSum += (int)mask[i];
         }
         
         for (int i = 0; i < (image.getWidth()-1); i++)
         {
             for (int j = 0; j < (image.getHeight()-1); j++)
             {
                r = g = b = 0;
                 counter = 0;
                 
                  for (int o = i - 1; o <= i + 1; o++)
                 {
                     for (int p = j - 1; p <= j + 1; p++)
                     {
                         if ((o == -1 && (p == -1 || p == image.getHeight())) || (o == image.getWidth() && (p == -1 || p == image.getHeight())))
                             c = image.getPixel(i, j);
                         else if (o == -1 || o == image.getWidth())
                             c = image.getPixel(i, p);
                         else if (p == -1 || p == image.getHeight())
                             c = image.getPixel(o, j);
                         else
                             c = image.getPixel(o, p);

                         weight = (int)mask[counter];
                        
                         r += ( Color.red(c)* weight);
                         b += (Color.blue(c) * weight);
                         g += (Color.green(c) * weight);

                         counter++;
                     }
                 }
                 if (weightSum == 0)
                     weightSum = 1;
                 r = r / weightSum;
                 b = b / weightSum;
                 g = g / weightSum;
                 
                 
                 
                 if (r < 0)
                     r = 0;
                 if (r > 255)
                     r = 255;

                 if (b < 0)
                     b = 0;
                 if (b > 255)
                     b = 255;

                 if (g < 0)
                     g = 0;
                 if (g > 255)
                     g = 255;
                 int x=Color.rgb(r,g,b);

                
                 
                 preview.setPixel(i, j, x);


             }

         }
         return preview;
	}
}

Kod wywoływania filtru w zależności od wybranego filtru:

Button edges=(Button)findViewById(R.id.button1);
		Button blur=(Button)findViewById(R.id.button2);
		Button sharpening=(Button)findViewById(R.id.button4);
		Button laplacian=(Button)findViewById(R.id.button3);
		edges.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				Intent intent=getIntent();
				final Uri uri=intent.getParcelableExtra("imageUri");
				
				
				
				int[] edge = {0, 0, 0,
                        -1,  1, 0,
                        0, 0, 0};
				String str=new String("Trwa przetwarzanie...");
				Toast.makeText(FiltersMenu.this, str , Toast.LENGTH_SHORT).show();
				Intent intent1=new Intent(FiltersMenu.this,DisplayingProcessedImage.class);
				intent1.putExtra("filtr", edge);
				intent1.putExtra("imageUri", uri);
				startActivity(intent1);
				
			}
		});
		blur.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				Intent intent=getIntent();
				final Uri uri=intent.getParcelableExtra("imageUri");
				
				
				
				int[] blur = { 
					    1, 1, 1, 
					    1, 1, 1, 
					    1, 1, 1 };
				String str=new String("Trwa przetwarzanie...");
				Toast.makeText(FiltersMenu.this, str , Toast.LENGTH_SHORT).show();
				Intent intent1=new Intent(FiltersMenu.this,DisplayingProcessedImage.class);
				intent1.putExtra("filtr", blur);
				intent1.putExtra("imageUri", uri);
				startActivity(intent1);
				
			}
		});
		
		sharpening.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				Intent intent=getIntent();
				final Uri uri=intent.getParcelableExtra("imageUri");
				
				
				
				int[] sharpening = { 0, -1, 0,
                        -1,  5, -1,
                         0, -1, 0};
				String str=new String("Trwa przetwarzanie...");
				Toast.makeText(FiltersMenu.this, str , Toast.LENGTH_SHORT).show();
				Intent intent1=new Intent(FiltersMenu.this,DisplayingProcessedImage.class);
				intent1.putExtra("filtr", sharpening);
				intent1.putExtra("imageUri", uri);
				startActivity(intent1);
				
			}
		});
		
		laplacian.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				Intent intent=getIntent();
				final Uri uri=intent.getParcelableExtra("imageUri");
				
				
				
				int[] laplacian = { 0, -1, 0,
                        -1, 4, -1,
                         0, -1, 0};
				String str=new String("Trwa przetwarzanie...");
				Toast.makeText(FiltersMenu.this, str , Toast.LENGTH_SHORT).show();
				Intent intent1=new Intent(FiltersMenu.this,DisplayingProcessedImage.class);
				intent1.putExtra("filtr", laplacian);
				intent1.putExtra("imageUri", uri);
				startActivity(intent1);
				
			}
		});
	}

Wyświetlenie wynikowego obrazka:


public class DisplayingProcessedImage extends Activity {

	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_displaying_processed_image);
		Intent intent=getIntent();
		Uri uri=intent.getParcelableExtra("imageUri");
		int[] filtr=intent.getIntArrayExtra("filtr");
		String str=uri.toString();
		Bitmap bitmap=BitmapFactory.decodeFile(str);
		
		Bitmap bitmap2 = bitmap.copy(bitmap.getConfig(), true);
		
		
	
		
		
	
		ConvolutionFilter filter=new ConvolutionFilter();
		
		ImageView imgView;
		imgView = (ImageView) findViewById(R.id.image1);
		imgView.setImageBitmap(filter.apply_Mask(filtr, bitmap2));
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.displaying_processed_image, menu);
		return true;
	}
2

problemem jest zapewne to:
preview=image;
Jeśli rozumiesz jak działają referencje w java to powinieneś rozumieć, że używasz modyfikowaną bitmapę do bieżących obliczeń.

0

@MarekR22 Jesteś boski, zapomniałem skopiować bitmapę :)
Wszystko już działa jak powinno.

1 użytkowników online, w tym zalogowanych: 0, gości: 1