Jeżeli robisz foreach'a po images to nie musisz ich usuwać, bo pętla przejedzie się po nich raz.
W przykładzie robisz pętle po tablicy przycisków nie obrazków, czyli źle.
Możesz zrobić sobie pomocniczą ArrayListę gdzie będziesz trzymał obrazki odpowiadające buttonom (zamiast je ustawiać, bo tego nie chcesz).
Wtedy, gdy ktoś kliknie buttona, szukasz w tej liście pomocniczej po ID buttona jaki obrazek jest mu przypisany - i wtedy go ustawiasz.
Pisane na szybko, można trochę jeszcze ładniej to zrobić ale powinno działać:
ArrayList<ImageButton> buttons = new ArrayList<>();
ArrayList<Integer> buttonImages = new ArrayList<>();
for(int card : cards) {
int n1 = random.nextInt(buttons.length);
ImageButton button1 = buttons.get(n1);
buttonImages.add(button1.getId(), card);
buttons.remove(n1);
int n2 = random.nextInt(buttons.length);
ImageButton button2 = buttons.get(n2);
buttonImages.add(button2.getId(), card);
buttons.remove(n2);
}