Depending on the number of records you could try to use the following query (check its execution time).
select d.everyminute,
(select count(*) from visitor
where `timestamp` between d.everyminute and
d.everyminute + interval 59 second) cnt
from
(
select @rownum:=@rownum+1,
date('2012-02-15') + interval (@rownum-1) minute everyminute from
(select 0 union all select 1 union all select 2) t,
(select 0 union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all select 7 union all
select 8 union all select 9) t1,
(select 0 union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all select 7 union all
select 8 union all select 9) t2,
(select 0 union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all select 7 union all
select 8 union all select 9) t3,
(select @rownum:=0) r where @rownum < 24*60
) d
The result is (I put some timestamps into the test DB)
2012-02-15 00:00:00 0
2012-02-15 00:01:00 0
2012-02-15 00:02:00 2
2012-02-15 00:03:00 1
2012-02-15 00:04:00 0
2012-02-15 00:05:00 1
2012-02-15 00:06:00 0
2012-02-15 00:07:00 0
2012-02-15 00:08:00 0
2012-02-15 00:09:00 0
2012-02-15 00:10:00 0
and so on until 2012-02-15 23:59:00
the existing records had timestamps 2012-02-15 00:02:00
, 2012-02-15 00:02:00
, 2012-02-15 00:03:00
and 2012-02-15 00:05:00
ps: to take into account summer/winter time jump you can rewrite where @rownum < 24*60
as having everyminute < (date('2012-02-15') + interval 1 day - interval 1 minute)
As you can see, it counts every minute even when there are no records in db within this minute.