Assumptions on ImageSet.lamda variable

This came up while working `ImageSet(...).intersect(S.Reals).
The assumption on the lambda variable in `ImageSet` is complex by default which causes inconvenience like 
```
In[]: (n + I*n).as_imag_real()
Out[]:(re(n) - im(n), re(n) + im(n))
```
It is better if the assumptions on the variable is decided by the base_set of the ImageSet.

This sort of dispatching on type is, in my opinion, an anti-pattern.  Common refactorings are methods like `_eval_imageset`.