// Гистограмма для sawtooth1Image()
private void sawtooth1Image() {
if (image != null) {
// Запрос значения порогов в цикле до тех пор, пока пользователь не введет правильные значения
float t1 = 0, t2 = 0;
boolean valid = false;
while (!valid) {
t1 = userInput("Введите значение порога 1: ", 0, 1);
t2 = userInput("Введите значение порога 2: ", 0, 1);
if (t2 > t1) {
valid = true;
} else {
JOptionPane.showMessageDialog(null, “Значение порога 2 должно быть больше порога 1”);
}
}

BufferedImage sawtoothContrastImage = sawtoothContrastUp(image, t1, t2);

setImageIcon(sawtoothContrastImage);
saveImage(sawtoothContrastImage);

int[] originalHistogram = getHistogram(image);
int[] sawtoothHistogram = getHistogram(sawtoothContrastImage);

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

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

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

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

// Гистограмма для sawtooth2Image()
private void sawtooth2Image() {
if (image != null) {
// Запрос значения порогов в цикле до тех пор, пока пользователь не введет правильные значения
float t1 = 0, t2 = 0;
boolean valid = false;
while (!valid) {
t1 = userInput("Введите значение порога 1: ", 0, 1);
t2 = userInput("Введите значение порога 2: ", 0, 1);
if (t2 > t1) {
valid = true;
} else {
JOptionPane.showMessageDialog(null, “Значение порога 2 должно быть больше порога 1”);
}
}

BufferedImage sawtoothContrastImage = sawtoothContrastDown(image, t1, t2);

setImageIcon(sawtoothContrastImage);
saveImage(sawtoothContrastImage);

int[] originalHistogram = getHistogram(image);
int[] sawtoothHistogram = getHistogram(sawtoothContrastImage);

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

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

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

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

// Гистограмма для sawtooth3Image()
private void sawtooth3Image() {
if (image != null) {
// Запрос значения порогов в цикле до тех пор, пока пользователь не введет правильные значения
float t1 = 0, t2 = 0;
boolean valid = false;
while (!valid) {
t1 = userInput("Введите значение порога 1: ", 0, 1);
t2 = userInput("Введите значение порога 2: ", 0, 1);
if (t2 > t1) {
valid = true;
} else {
JOptionPane.showMessageDialog(null, “Значение порога 2 должно быть больше порога 1”);
}
}

BufferedImage sawtoothContrastImage1 = sawtoothContrastUp(image, t1, t2);

BufferedImage sawtoothContrastImage2 = sawtoothContrastDown(image, t1, t2);

BufferedImage combinedImage = combineImages(sawtoothContrastImage1, sawtoothContrastImage2);

setImageIcon(combinedImage);
saveImage(combinedImage);

int[] originalHistogram = getHistogram(image);
int[] sawtoothHistogram = getHistogram(combinedImage);

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

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

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

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

// Гистограмма для sawtooth4Image()
private void sawtooth4Image() {
if (image != null) {
// Запрос значения порогов в цикле до тех пор, пока пользователь не введет правильные значения
float t1 = 0, t2 = 0;
boolean valid = false;
while (!valid) {
t1 = userInput("Введите значение порога 1: ", 0, 1);
t2 = userInput("Введите значение порога 2: ", 0, 1);
if (t2 > t1) {
valid = true;
} else {
JOptionPane.showMessageDialog(null, “Значение порога 2 должно быть больше порога 1”);
}
}

BufferedImage sawtoothContrastImage1 = sawtoothContrastUp(image, t1, t2);

BufferedImage sawtoothContrastImage2 = sawtoothContrastDown(image, t1, t2);

BufferedImage combinedImage = combineImages(sawtoothContrastImage1, sawtoothContrastImage2, sawtoothContrastImage1);

setImageIcon(combinedImage);
saveImage(combinedImage);

int[] originalHistogram = getHistogram(image);
int[] sawtoothHistogram = getHistogram(combinedImage);

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

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

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

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

// Функция пилообразного контрастирования с порогами и направлением вверх
private BufferedImage sawtoothContrastUp(BufferedImage image, float t1, float t2) {
BufferedImage output = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
int pixel = image.getRGB(i, j);
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = pixel & 0xff;
int brightness = (int) (0.2126 * red + 0.7152 * green + 0.0722 * blue);
if (brightness < t1) {
output.setRGB(i, j, new Color(0, 0, 0).getRGB());
} else if (brightness >= t1 && brightness < t2) {
int value = (int) (255 * (brightness - t1) / (t2 - t1));
output.setRGB(i, j, new Color(value, value, value).getRGB());
} else if (brightness >= t2) {
output.setRGB(i, j, new Color(255, 255, 255).getRGB());
}
}
}
return output;
}

// Функция пилообразного контрастирования