При вводе порогов, изображения меняется только один раз. Исправить в sawtooth4Image()
					// Гистограмма для sawtooth3Image()
					private void sawtooth3Image() {
					if (image != null) {
					BufferedImage combinedImage = deepCopy(image); // Создаем копию исходного изображения

					// Запрос значения порогов в цикле до тех пор, пока пользователь не введет правильные значения
					float t1 = 0, t2 = 0;
					boolean valid = false;
					while (!valid) {
					t1 = userInput("Введите значение порога 1: ", 0, 1);
					t2 = userInput("Введите значение порога 2: ", 0, 1);
					if (t2 > t1) {
					BufferedImage sawtoothContrastImage1 = sawtoothContrastUp(image, t1, t2); // Применяем контрастирование для первого изображения
					BufferedImage sawtoothContrastImage2 = sawtoothContrastDown(image, t1, t2); // Применяем контрастирование для второго изображения
					// Объединяем полученные изображения
					for (int y = 0; y < combinedImage.getHeight(); y++) {
					for (int x = 0; x < combinedImage.getWidth(); x++) {
					int rgb1 = sawtoothContrastImage1.getRGB(x, y);
					int rgb2 = sawtoothContrastImage2.getRGB(x, y);
					int red1 = (rgb1 >> 16) & 0xFF;
					int green1 = (rgb1 >> 8) & 0xFF;
					int blue1 = rgb1 & 0xFF;
					int red2 = (rgb2 >> 16) & 0xFF;
					int green2 = (rgb2 >> 8) & 0xFF;
					int blue2 = rgb2 & 0xFF;
					int red = (int) ((red1 + red2) * 0.5);
					int green = (int) ((green1 + green2) * 0.5);
					int blue = (int) ((blue1 + blue2) * 0.5);
					combinedImage.setRGB(x, y, (red << 16) | (green << 8) | blue);
					}
					}
					valid = true;
					} else {
					JOptionPane.showMessageDialog(null, "Значение порога 2 должно быть больше порога 1");
					}
					}

					setImageIcon(combinedImage);
					saveImage(combinedImage);

					int[] originalHistogram = ImageReader.getImageHistogram(image);
					int[] sawtoothHistogram = ImageReader.getImageHistogram(combinedImage);

					JFrame histogramFrame = new JFrame("Гистограммы");
					histogramFrame.setLayout(new GridLayout(1, 2, 10, 10));

					JPanel originalHistogramPanel = ImageReader.createHistogramPanel(originalHistogram, "Гистограмма исходного изображения");

					JPanel sawtoothHistogramPanel = ImageReader.createHistogramPanel(sawtoothHistogram, "Гистограмма после контрастирования");

					histogramFrame.add(originalHistogramPanel);
					histogramFrame.add(sawtoothHistogramPanel);
					histogramFrame.pack();
					histogramFrame.setLocationRelativeTo(null);
					histogramFrame.setVisible(true);
					}
					}
					// Создание глубокой копии изображения
					private BufferedImage deepCopy3(BufferedImage image) {
					ColorModel colorModel = image.getColorModel();
					boolean isAlphaPremultiplied = colorModel.isAlphaPremultiplied();
					WritableRaster raster = image.copyData(image.getRaster().createCompatibleWritableRaster());
					return new BufferedImage(colorModel, raster, isAlphaPremultiplied, null);
					}
					// Гистограмма для sawtooth4Image()
					private void sawtooth4Image() {
					boolean valid = true; // Убираем переменную valid из условия, чтобы ее значение сохранялось между вызовами метода
					while (valid) { // Используем цикл, чтобы можно было изменять изображение несколько раз
					if (image != null) {
					// Запрос значения порогов в цикле до тех пор, пока пользователь не введет правильные значения
					float t1 = userInput("Введите значение порога 1: ", 0, 1);
					float t2 = userInput("Введите значение порога 2: ", 0, 1);
					if (t2 > t1) {
					BufferedImage sawtoothContrastImage1 = sawtoothContrastUp(image, t1, t2);
					BufferedImage sawtoothContrastImage2 = sawtoothContrastDown(image, t1, t2);
					BufferedImage combinedImage = combineImages(sawtoothContrastImage1, sawtoothContrastImage2, sawtoothContrastImage1);

					setImageIcon(combinedImage);
					saveImage(combinedImage);

					int[] originalHistogram = ImageReader.getImageHistogram(image);
					int[] sawtoothHistogram = ImageReader.getImageHistogram(combinedImage);

					JFrame histogramFrame = new JFrame("Гистограммы");
					histogramFrame.setLayout(new GridLayout(1, 2, 10, 10));

					JPanel originalHistogramPanel = ImageReader.createHistogramPanel(originalHistogram, "Гистограмма исходного изображения");

					JPanel sawtoothHistogramPanel = ImageReader.createHistogramPanel(sawtoothHistogram, "Гистограмма после контрастирования");

					histogramFrame.add(originalHistogramPanel);
					histogramFrame.add(sawtoothHistogramPanel);
					histogramFrame.pack();
					histogramFrame.setLocationRelativeTo(null);
					histogramFrame.setVisible(true);

					image = combinedImage; // Сохраняем измененное изображение в переменную image

					// Запрос новых значений порогов
					} else {
					JOptionPane.showMessageDialog(null, "Значение порога 2 должно быть больше порога 1");
					}
					} else {
					valid = false;
					}
					}
					}